콘텐츠로 이동

Exec approvals로 안전하게 명령어 실행하기

에이전트에게 내 컴퓨터나 서버의 권한을 줄 때, 혹시라도 실수로 중요한 파일을 지우거나 이상한 명령어를 실행하면 어쩌나 걱정해 본 적 있으시죠? 자동화는 편리하지만, 최소한의 안전장치는 꼭 필요해요. 내 환경을 보호하면서도 에이전트의 능력을 활용할 수 있는 방법을 소개할게요.

Exec approvals는 샌드박스 에이전트가 실제 호스트(gateway 또는 node)에서 명령어를 실행할 때 적용되는 안전장치예요. 정책(policy), 화이트리스트(allowlist), 그리고 선택적인 사용자 승인이 모두 일치해야 명령어가 실행됩니다. 일종의 안전 인터락이라고 생각하면 쉬워요.

  • Gateway host (Gateway 장비의 openclaw 프로세스)
  • Node host (macOS companion app 또는 headless node host)

Exec approvals는 실행 호스트에서 로컬로 강제 적용됩니다. tools.exec.* 정책과 approvals 기본값 중 더 엄격한 설정이 우선순위를 가져요.

승인 설정은 실행 호스트의 로컬 JSON 파일에 저장됩니다. ~/.openclaw/exec-approvals.json

아래는 exec-approvals.json 파일의 예시 구조입니다. 이 설정을 통해 에이전트별로 보안 수준과 승인 방식을 정의할 수 있어요.

{
"version": 1,
"socket": {
"path": "~/.openclaw/exec-approvals.sock",
"token": "base64url-token"
},
"defaults": {
"security": "deny",
"ask": "on-miss",
"askFallback": "deny",
"autoAllowSkills": false
},
"agents": {
"main": {
"security": "allowlist",
"ask": "on-miss",
"askFallback": "deny",
"autoAllowSkills": true,
"allowlist": [
{
"id": "B0C8C0B3-2C2D-4F8A-9A3C-5A4B3C2D1E0F",
"pattern": "~/Projects/**/bin/rg",
"lastUsedAt": 1737150000000,
"lastUsedCommand": "rg -n TODO",
"lastResolvedPath": "/Users/user/Projects/.../bin/rg"
}
]
}
}
}
  • macOS 환경: node host service가 system.run 요청을 받으면 로컬 IPC를 통해 macOS app으로 전달합니다. macOS app이 승인 여부를 확인하고 UI 컨텍스트에서 명령어를 실행해요.
  • 보안 바운더리: Gateway 인증을 받은 호출자는 해당 Gateway의 신뢰할 수 있는 운영자로 간주됩니다. Exec approvals는 권한 분리 도구가 아니라 실수로 인한 실행 위험을 줄이는 용도예요.

문제가 발생하면 다음 사항을 확인해 보세요.

  • Companion app UI를 사용할 수 없는 경우: 승인 프롬프트가 필요한 모든 요청은 ask fallback 설정에 따라 처리됩니다. 기본값은 거절(deny)이에요.
  • 명령어 실행 거부: 승인된 이후라도 실행 직전에 스크립트 내용이 변경되면 실행이 거부됩니다. 이는 승인 시점과 실행 시점 사이의 내용 불일치(drift)를 방지하기 위함이에요.

설정이나 구현 중에 궁금한 점이 생기면 언제든 물어봐 주세요!

AI Setup Assistant

  • Gateway 보안 정책 설정하기
  • macOS companion app 연동 가이드

에이전트에게 내 컴퓨터의 실행 권한을 맡길 때, 혹시나 의도치 않은 명령어를 실행하지 않을까 걱정해 본 적 있으신가요? 매번 일일이 허가 버튼을 누르는 건 번거롭고, 그렇다고 모든 권한을 다 열어두기엔 보안이 불안한 그 마음을 잘 알고 있어요.

이런 고민을 해결하기 위해 Policy knobs를 어떻게 설정하면 좋을지 바로 알아볼게요.

  • macOS app (여러 에이전트를 관리하는 경우 필요해요)
  • Gateway RPC (Auto-allow 기능을 사용하는 경우 필요해요)

에이전트의 실행 권한을 제어하는 가장 빠른 방법은 exec.security와 exec.ask를 설정하는 거예요.

  1. 보안 수준 정하기: exec.security를 allowlist로 설정해 허용된 명령어만 실행하게 하세요.
  2. 확인 절차 설정: exec.ask를 on-miss로 설정해 Allowlist에 없는 경우에만 묻도록 만드세요.
  3. 예외 상황 대비: askFallback을 설정해 UI를 사용할 수 없을 때의 동작을 정의하세요.

에이전트가 호스트에서 실행 요청을 보낼 때의 보안 수준을 결정해요.

  • deny: 모든 호스트 실행 요청을 차단해요.
  • allowlist: Allowlist에 등록된 명령어만 허용해요.
  • full: 모든 실행을 허용해요 (elevated와 같아요).

명령어를 실행하기 전 사용자에게 물어볼지 결정해요.

  • off: 절대 묻지 않아요.
  • on-miss: Allowlist와 일치하지 않을 때만 물어봐요.
  • always: 모든 명령어 실행 시 매번 물어봐요.

사용자 확인이 필요하지만 UI에 연결할 수 없는 상황(예: headless 환경)에서 어떻게 할지 결정해요.

  • deny: 차단해요.
  • allowlist: Allowlist와 일치하는 경우에만 허용해요.
  • full: 허용해요.

Allowlist 관리하기 (에이전트별 설정)

섹션 제목: “Allowlist 관리하기 (에이전트별 설정)”

Allowlist는 에이전트별로 관리돼요. 만약 여러 개의 에이전트를 사용 중이라면, macOS app에서 편집할 에이전트를 전환하며 설정해야 해요.

패턴은 대소문자를 구분하지 않는 glob match 방식을 사용해요. 주의할 점은 패턴이 반드시 binary paths로 확인되어야 한다는 거예요. 파일 이름만 적은 항목(basename-only)은 무시되니 주의하세요. 기존의 agents.default 항목들은 로드될 때 자동으로 agents.main으로 옮겨져요.

Allowlist 예시:

  • ~/Projects/**/bin/peekaboo
  • ~/.local/bin/*
  • /opt/homebrew/bin/rg

각 Allowlist 항목은 다음 정보들을 추적해요.

  • id: UI 식별을 위한 고유 UUID (선택 사항)
  • last used: 마지막 사용 시간
  • last used command: 마지막으로 사용된 명령어
  • last resolved path: 마지막으로 확인된 경로

Auto-allow skill CLIs 기능을 켜면, 이미 알고 있는 skill에서 참조하는 실행 파일들을 노드(macOS node 또는 headless node host)에서 자동으로 Allowlist에 포함된 것처럼 취급해요.

이 기능은 Gateway RPC를 통해 skills.bins를 가져와서 실행 파일 목록을 확인해요. 만약 엄격하게 수동으로만 Allowlist를 관리하고 싶다면 이 기능을 끄면 돼요.

보안 참고 사항:

  • 이 기능은 수동 경로 설정과는 별개로 작동하는 암묵적인 편의 기능이에요.
  • Gateway와 노드가 동일한 신뢰 경계(trust boundary) 안에 있는 신뢰할 수 있는 환경을 위해 만들어졌어요.
  • 엄격하고 명시적인 신뢰 관리가 필요하다면 autoAllowSkills: false로 두고 수동으로 Allowlist를 관리하세요.

Q: UI를 사용할 수 없는 환경에서 승인 요청이 발생하면 어떻게 되나요? A: askFallback 설정에 따라 동작이 달라져요. 안전을 원한다면 deny로 설정하고, Allowlist 기반의 실행만 허용하고 싶다면 allowlist를 선택하세요.

Q: Allowlist에 명령어를 추가했는데 작동하지 않아요. A: 입력한 경로가 실제 binary paths인지 확인해 보세요. 단순히 명령어 이름만 적으면 무시될 수 있어요. 또한 glob 패턴이 올바른지도 다시 한번 체크해 보세요.


더 궁금한 점이 있거나 설정 중에 막히는 부분이 있다면 AI Setup Assistant에게 물어보세요!

제한된 환경에서 명령어를 실행하다 보면 승인 알림이 계속 떠서 개발 흐름이 끊길 때가 많아요. 보안을 지키면서도 단순한 데이터 처리는 좀 더 직접적으로 할 수 없을까 고민하게 되죠. 특히 파이프라인 중간에서 데이터를 가공하는 도구들을 쓸 때 이런 불편함이 더 크게 느껴집니다.

tools.exec.safeBins는 이런 상황을 위해 설계되었어요. jq와 같이 stdin-only로 동작하는 바이너리들을 별도의 allowlist 등록 없이도 실행할 수 있게 해주는 기능입니다.

이 기능을 사용하기 위해 필요한 조건들입니다.

  • tools.exec.safeBins 설정 권한
  • /bin 또는 /usr/bin에 위치한 대상 바이너리 (또는 safeBinTrustedDirs 설정)
  • ~/.openclaw/exec-approvals.json 파일 접근 권한 (allowlist 확인용)

5분 안에 safe bins를 설정하고 사용하는 방법입니다.

  1. 기본 제공 바이너리 확인: jq, cut, uniq, head, tail, tr, wc는 기본적으로 safe bins에 포함되어 있습니다.
  2. 명령어 실행: 이 도구들을 사용할 때는 파일을 직접 인자로 넘기지 말고, stdin 스트림을 통해서만 데이터를 전달하세요.
  3. 커스텀 바이너리 등록: 만약 myfilter라는 도구를 추가하고 싶다면, 설정 파일에 다음과 같이 프로필을 정의하세요.
{
tools: {
exec: {
safeBins: ["jq", "myfilter"],
safeBinProfiles: {
myfilter: {
minPositional: 0,
maxPositional: 0,
allowedValueFlags: ["-n", "--limit"],
deniedFlags: ["-f", "--file", "-c", "--command"],
},
},
},
},
}

Safe bins는 일반적인 신뢰 리스트가 아니라, 스트림 필터를 위한 좁고 빠른 경로라고 생각해야 해요. 보안을 위해 몇 가지 엄격한 규칙이 적용됩니다.

Safe bins는 위치 기반 파일 인자(positional file args)나 경로처럼 보이는 토큰을 거부합니다. 오직 들어오는 스트림만 처리할 수 있어요. sort -o, grep -f, jq -f 같이 파일을 직접 읽거나 쓰는 옵션들은 모두 차단됩니다.

python3, node, ruby, bash, sh, zsh 같은 바이너리는 절대 safeBins에 추가하지 마세요. 설계를 통해 코드를 실행하거나 파일을 읽을 수 있는 명령어가 필요하다면, 명시적인 allowlist 항목을 만들고 승인 프롬프트를 켜두는 것이 좋습니다.

검증은 오직 argv의 형태만 보고 판단합니다. 호스트 파일 시스템에 파일이 존재하는지 체크하지 않기 때문에, allow/deny 차이로 인한 정보 유출(oracle behavior)을 방지할 수 있어요.

  • 변수 확장 금지: *나 $HOME 같은 패턴은 실행 시점에 리터럴 텍스트로 처리됩니다. 이를 통해 파일 읽기를 시도하는 행위를 차단해요.
  • 신뢰할 수 있는 경로: 바이너리는 /bin, /usr/bin 같은 신뢰할 수 있는 디렉토리에 있어야 합니다. PATH에 등록된 경로는 자동으로 신뢰하지 않아요. Homebrew 등을 사용한다면 tools.exec.safeBinTrustedDirs에 /opt/homebrew/bin을 직접 추가해야 합니다.
항목tools.exec.safeBinsAllowlist (exec-approvals.json)
목표좁은 범위의 stdin 필터 자동 허용특정 실행 파일에 대한 명시적 신뢰
매칭 방식실행 파일 이름 + safe-bin argv 정책확인된 실행 파일 경로 glob 패턴
인자 범위safe-bin profile 및 리터럴 토큰 규칙에 의해 제한경로 매칭만 수행; 인자 관리는 사용자의 책임
일반적인 예시jq, head, tail, wcpython3, node, ffmpeg, 커스텀 CLI
최적의 용도저위험 텍스트 변환 파이프라인광범위한 동작이나 부수 효과가 있는 도구

문제가 발생했을 때 확인할 수 있는 내용입니다.

  • grep이나 sort가 작동하지 않나요?: 이 도구들은 기본 리스트에 없습니다. 직접 추가하더라도 grep은 반드시 -e 또는 --regexp를 사용해 패턴을 제공해야 합니다. 위치 기반 패턴 형식은 파일 인자로 오용될 수 있어 거부됩니다.
  • tools.exec.safe_bins_interpreter_unprofiled 경고: 프로필 정의 없이 인터프리터나 런타임 바이너리를 safeBins에 넣으면 발생합니다. openclaw security audit으로 확인하세요.
  • 설정 누락: openclaw doctor --fix를 실행하면 누락된 커스텀 safeBinProfiles.<bin> 항목을 {} 형태로 자동 생성해 줍니다. 이후에 세부 규칙을 직접 수정하세요.
  • 쉘 특수 문자 문제: &&, ||, ;, | 같은 문자가 포함된 원시 쉘 텍스트는 쉘 바이너리 자체가 allowlist에 있지 않는 한 승인 거부될 수 있습니다.

AI Setup Assistant

---
title: "Control UI에서 실행 승인(Exec approvals) 관리하기"
description: "Control UI를 통해 에이전트의 실행 승인 정책과 허용 리스트를 효율적으로 설정하고 관리하는 방법을 알아봅니다."
---
터미널에서 명령어를 실행할 때마다 보안과 편의성 사이에서 고민한 적 많으시죠? 모든 실행을 수동으로 확인하자니 흐름이 끊기고, 그렇다고 다 허용하자니 불안할 때가 있어요. 이럴 때 실행 승인(Exec approvals) 설정을 잘 활용하면 안전하면서도 매끄러운 개발 환경을 만들 수 있습니다.
### What You'll Need
시작하기 전에 소스 문서에서 언급된 다음 사항들이 준비되었는지 확인해 주세요.
* **Gateway**: 로컬 승인을 처리합니다.
* **Node**: `system.execApprovals.get/set`을 광고(advertise)하는 macOS 앱 또는 headless 노드 호스트가 필요합니다.
* **파일 접근 권한**: 노드가 아직 기능을 광고하지 않는 경우 `~/.openclaw/exec-approvals.json` 파일을 직접 수정해야 할 수 있습니다.
### Quick Start
5분 만에 실행 승인 정책을 설정하는 방법입니다.
1. **Control UI 접속**: **Control UI → Nodes → Exec approvals** 카드로 이동하세요. 여기에서 기본값, 에이전트별 오버라이드, 허용 리스트(allowlists)를 편집할 수 있습니다.
2. **범위(Scope) 선택**: 설정하려는 대상(기본값 또는 특정 에이전트)을 선택하세요.
3. **정책 수정**: 정책을 조정하고 허용 리스트 패턴을 추가하거나 제거합니다. UI에 패턴별로 **마지막 사용(last used)** 메타데이터가 표시되므로 리스트를 깔끔하게 유지하기 좋아요.
4. **저장**: 설정을 마쳤다면 **Save**를 누르세요.
5. **타겟 선택**: 설정을 적용할 대상으로 **Gateway**(로컬 승인) 또는 **Node**를 선택할 수 있습니다.
CLI가 더 편하시다면 `openclaw approvals` 명령어를 사용해 보세요. Gateway와 Node 편집을 모두 지원합니다. 자세한 내용은 [Approvals CLI](/docs/cli/approvals) 문서에서 확인하실 수 있어요.
#### 승인 워크플로우 이해하기
승인이 필요한 프롬프트가 발생하면 Gateway가 운영자 클라이언트에게 `exec.approval.requested` 메시지를 브로드캐스트합니다. Control UI나 macOS 앱에서 `exec.approval.resolve`를 통해 이를 해결하면, Gateway가 승인된 요청을 노드 호스트로 전달하는 방식이에요.
* **Node 호스트의 경우**: 승인 요청에 표준 `systemRunPlan` 페이로드가 포함됩니다. Gateway는 승인된 `system.run` 요청을 전달할 때 이 플랜을 커맨드, cwd, 세션 컨텍스트의 권위 있는 기준으로 사용합니다.
* **즉시 반환**: 승인이 필요할 때 실행 도구는 즉시 승인 ID를 반환합니다. 이 ID를 사용해 나중에 `Exec finished` 또는 `Exec denied` 이벤트를 연결해서 확인할 수 있습니다. 타임아웃 내에 결정이 내려지지 않으면 거절된 것으로 간주됩니다.
확인 대화상자에서는 다음 정보를 확인할 수 있습니다:
- command + args
- cwd
- agent id
- resolved executable path
- host + policy metadata
선택 가능한 작업은 세 가지입니다:
- **Allow once**: 이번 한 번만 실행합니다.
- **Always allow**: 허용 리스트에 추가하고 실행합니다.
- **Deny**: 실행을 차단합니다.
### Troubleshooting
설정 중에 문제가 생겼나요? 소스 문서에서 제안하는 해결 방법입니다.
* **노드가 실행 승인 설정을 광고하지 않을 때**: 노드가 아직 `system.execApprovals.get/set` 기능을 제공하지 않는다면, 해당 노드 호스트의 `~/.openclaw/exec-approvals.json` 파일을 직접 열어서 편집해야 합니다.
궁금한 점이 더 있다면 [AI Setup Assistant](/docs/#docs-chat)에게 물어보세요!
### What's Next
* [Approvals CLI](/docs/cli/approvals) - 명령줄에서 승인 정책 관리하기

터미널이나 특정 UI에서 승인 요청이 올 때마다 매번 화면을 전환하는 건 정말 번거로운 일이죠. 특히 동료들과 이미 대화 중인 Slack이나 Discord를 벗어나야 할 때 개발 흐름이 뚝 끊기곤 해요.

명령 실행 승인 알림을 평소 사용하는 채팅 채널로 바로 받고, 그 자리에서 바로 승인할 수 있다면 훨씬 편해질 거예요. 별도의 복잡한 도구 없이 기존의 outbound delivery pipeline을 통해 이 과정을 처리할 수 있습니다.

이 기능을 사용하기 위해 필요한 조건들입니다.

  • approvals 설정을 수정할 수 있는 권한
  • 연결된 채팅 채널 (Slack, Telegram, Discord 등)
  • 명령을 실행할 수 있는 authorized senders 권한

5분 안에 설정을 마치고 채팅창에서 승인을 시작해 보세요.

먼저 approvals.exec 설정을 활성화해야 합니다. 아래 예시처럼 어떤 에이전트와 세션의 요청을 어느 채널로 보낼지 지정할 수 있어요.

{
approvals: {
exec: {
enabled: true,
mode: "session", // "session" | "targets" | "both"
agentFilter: ["main"],
sessionFilter: ["discord"], // substring or regex
targets: [
{ channel: "slack", to: "U12345678" },
{ channel: "telegram", to: "123456789" },
],
},
},
}

승인 요청이 채널에 도착하면 /approve 명령어를 사용해 응답하세요. 세 가지 옵션이 있습니다.

/approve <id> allow-once
/approve <id> allow-always
/approve <id> deny

macOS 환경에서는 보안을 위해 다음과 같은 IPC(Inter-Process Communication) 흐름을 따릅니다.

Gateway -> Node Service (WS)
| IPC (UDS + token + HMAC + TTL)
v
Mac App (UI + approvals + system.run)

보안을 위해 Unix socket mode는 0600으로 제한되며, 인증 토큰은 exec-approvals.json에 저장됩니다. 동일한 UID를 가진 프로세스인지 체크하고, nonce와 HMAC 토큰, request hash를 조합한 challenge/response 방식과 짧은 TTL을 사용해 안전을 보장합니다.

명령 실행의 전체 라이프사이클은 시스템 메시지로 확인할 수 있어요. Node가 이벤트를 보고하면 에이전트 세션에 다음과 같이 표시됩니다.

  • Exec running: 실행 시간이 임계값을 초과할 때만 표시됩니다.
  • Exec finished: 실행이 완료되었을 때 표시됩니다.
  • Exec denied: 실행이 거부되었을 때 표시됩니다.

Gateway-host 실행 승인도 명령이 종료될 때 동일한 이벤트를 발생시킵니다. 승인이 필요한 실행 건은 runId로 승인 ID를 재사용하기 때문에 서로 연관 지어 확인하기 쉽습니다.

설정이나 실행 과정에서 문제가 생겼을 때 확인해야 할 포인트입니다.

  • 승인 요청이 오지 않는 경우: 요청자가 authorized senders에 포함되어 있는지 확인하세요. 권한이 없는 사용자는 /exec 명령을 내릴 수 없습니다.
  • 보안 수준 조정: 모든 권한을 허용하는 full 모드는 매우 강력하므로, 가급적 allowlist를 사용하는 것이 좋습니다.
  • 특정 에이전트의 승인 누출: 에이전트별 allowlist를 설정하면 한 에이전트의 승인 요청이 다른 곳으로 새나가는 것을 방지할 수 있습니다.
  • 승인 단계 건너뛰기: /exec security=full은 인증된 운영자를 위한 편의 기능으로, 설계상 승인 단계를 건너뜁니다. 만약 호스트 실행을 완전히 차단하고 싶다면 approvals security를 deny로 설정하거나 tool policy에서 exec 도구를 차단하세요.

궁금한 점이 더 있다면 AI Setup Assistant에게 물어보세요.

OpenClaw

OpenClaw Expert

아직 막혀 있나요?

이 문서에서 답을 못 찾았다면 OpenClaw Expert에게 바로 물어보세요.