2026년 OpenClaw 플러그인 fail-closed·manifest 강제 선언: 원격 물리 Mac 7×24 게이트웨이에서 openclaw doctor 감사 체크리스트, ACP dispatch 스위치, 통제된 롤백 Runbook
(grep 수락 조각 + FAQ)
플랫폼·보안 엔지니어가 원격 물리 Mac을 무인 게이트웨이로 쓰면 플러그인 전부가 공급망이라는 사실을 금방 깨닫습니다. 허용 목록 한 줄이 새벽 3시에 선언되지 않은 네트워크·파일 접근을 열 수 있습니다. 이 글은 manifest 강제(유효 manifest 없으면 로드 금지)와 fail-closed(검증 실패 시 조용한 허용이 아니라 거부)를 누가 어떤 자세를 취할지, 의사결정 매트릭스 두 개, 7단계 롤백 런북, 복붙 grep, FAQ로 묶습니다. 도메인·샌드박스 출발 거버넌스와 맞물리게 하려면 더 읽기: OpenClaw Gateway 출발 거버넌스·도메인 허용·Sandbox·감사 로그(HITL) 원격 Mac 재현을 함께 두세요.
서론과 범위
랙에 둔 헤드리스 Mac에서 플러그인은 공격 표면의 일부입니다. 2026년 주류 패턴은 manifest 강제(규격에 맞는 manifest가 없으면 로드하지 않음)와 fail-closed(검증 실패 시 실행을 거부하고 조용히 허용하지 않음)의 결합입니다.
이 가이드는 그 자세를 doctor가 뒷받침하는 체크 항목과 변경 티켓에 붙일 grep으로 바꾸고, ACP(Agent Client Protocol) dispatch를 누가 플러그인 스케줄러에 들어올 수 있는지의 마스터 스위치로 봅니다. 스냅샷과 짝지어 두면 롤백 RTO가 점검 창 안에 남습니다. 벤더 모델 계약은 범위 밖이며, launchd가 서비스 사용자를 고정하고 WorkingDirectory를 핀한다고 가정합니다. 게이트웨이를 컨테이너로 올릴지 베어메탈로 둘지에 대한 실무 트레이드오프는 더 읽기: 원격 Mac에서 OpenClaw Docker vs 베어메탈·Compose 헬스 FAQ를 참고하세요. 외부 에이전트가 MCP로 도구를 붙는 경로는 더 읽기: 원격 물리 Mac OpenClaw MCP stdio·Streamable HTTP 런북과 교차 검토하면 좋습니다.
고통 포인트
- 제약: 암묵적 권한과 「돌아가니까 배포」.
fs,network,subprocess등 manifest에서 빠진 capability가 fail-open에서는 조용히 허용되는 경우가 많아 감사로 무엇이 허용됐는지 증명할 수 없습니다. - 숨은 비용: doctor 녹색 ≠ 정책 적용.
openclaw doctor가 런타임과 포트는 보여줘도 핫 리로드가 새 manifest 강제 플래그를 못 읽으면 외부 관찰은 여전히 레거시 동작일 수 있습니다. - 안정성·감사: 짝 없는 스냅샷으로는 롤백이 성립하지 않습니다. 공격적으로 fail-closed를 켜면 정상 자동화가 밤새 깨질 수 있는데, 설정+플러그인 번들 스냅샷 없이 JSON을 수동 편집하면 7×24 SLO를 깨뜨립니다.
fail-closed × manifest 의사결정 매트릭스
첫 표는 「얼마나 엄격할까」, 둘째는 「변경 신호마다 무엇을 검증할까」에 답합니다.
| 환경 | manifest | fail-closed | ACP dispatch |
|---|---|---|---|
| 프로덕션 7×24 게이트웨이 | 강제 | 켬 | 허용된 clientId·워크스페이스만 |
| 스테이징 통합 | 강제 | 켬(플러그인별 섀도 허용 가능) | 팀 테넌트 완화 + 전체 JSONL |
| 개발자 노트북 | 강제 권장(프로덕 미러) | 빠른 반복을 위해 선택 끔 | 로컬 전체 허용 또는 루프백 한정 |
| 변경 신호 | 권장 조치 | 추가 수락 |
|---|---|---|
| 신규 플러그인 또는 메이저 업그레이드 | 카나리아 노드 + 이중 manifest diff | doctor + 선언 스키마 버전 grep |
| 외부 ACP·에이전트 클라이언트 증가 | dispatch 허용 목록·레이트 리밋 강화 | requestId로 플러그인 스팬 추적 |
| 로그에 거부 급증 | 먼저 섀도 카운트, 이후 롤백 여부 결정 | 롤백 전후 5분 창 diff |
openclaw doctor 감사 체크리스트
doctor를 「정책이 실제로 로드됐다」는 증거로 쓰고, 변경 티켓마다 체크합니다(키 이름은 배포판 문서에 맞춰 openclaw.json 또는 환경 변수로 매핑).
- 런타임·PATH: launchd 사용자와 일치하는지,
which openclaw가 plist의 바이너리 경로와 같은지. - manifest 해석: 유효 플러그인 루트 출력, 강제 시 manifest 없는 디렉터리 거부.
- fail-closed 플래그: 불리언과 출처 파일 출력, WARN은 릴리스 차단.
- ACP dispatch: 스위치 상태와 허용 목록 크기, dispatch 켠 채 허용 목록이 비면 「들어올 클라이언트 없음」 경고가 나와야 합니다.
- 외부 헬스: 로컬
curl과/ready(있을 때)를 짝지어 자가 점검만 녹색이고 역프록시는 빨간 상황을 피합니다.
ACP dispatch 스위치
ACP dispatch는 IDE·CLI·외부 오케스트레이터 같은 에이전트 클라이언트 요청이 플러그인 스케줄러에 들어올 수 있는지를 가릅니다. fail-closed와 함께 쓸 때는 먼저 manifest로 플러그인 집합을 검증하고, 그다음 dispatch로 정문을 지키는 순서가 안전합니다. 그래야 탈취된 클라이언트가 고위험 훅으로 바로 뛰지 못합니다.
예시 JSON(프로덕션 전에 배포판 스키마로 치환):
{
"plugins": {
"requireManifest": true,
"failClosed": true,
"manifestSchemaVersion": "2026-05"
},
"acp": {
"dispatchEnabled": true,
"allowedClientIds": ["ci-runner-prod", "vscode-workspace-ops"],
"denyByDefault": true
}
}
allowedClientIds를 내부 OAuth 주체 또는 mTLS DN과 맞추고, 포렌식을 위해 clientId × pluginId 데카르트 곱을 JSONL에 남기세요.
수락용 grep 조각
아카이브 또는 라이브 워크스페이스에서 실행(경로 조정):
# fail-closed / requireManifest 플래그 명시 여부
grep -RniE 'failClosed|fail_closed|requireManifest|require_manifest' \
~/.config/openclaw ./openclaw.json 2>/dev/null
# 플러그인 디렉터리마다 manifest 존재(없으면 로드되면 안 됨)
find "$OPENCLAW_PLUGIN_ROOT" -maxdepth 2 -type f \( -name 'manifest.json' -o -name 'plugin.yaml' \) | wc -l
# 프로덕션에서 ACP dispatch 허용 목록은 비어 있으면 안 됨
grep -Rni 'dispatchEnabled|allowedClientIds|denyByDefault' ~/.config/openclaw ./openclaw.json 2>/dev/null
첫 grep이 아무 것도 안 남기면 암묵적 fail-open일 가능성이 큽니다. 근육 기억만으로 프로덕션 서명은 하지 마세요.
7단계 통제 롤백 런북
- 동결: 점검 공지 후 호출 표면을 넓히는 cron을 잠시 멈춥니다.
- 스냅샷:
openclaw.json, 플러그인 트리, launchd plist, doctor 표준 출력을 tar합니다. - manifest 강제 켬: 리로드, grep 검증, 「로드 거부」 카운터 관찰.
- fail-closed 켬: 미선언 capability에 대해 일관된 오류 코드, 5분치 JSONL 베이스라인.
- ACP dispatch 조이기: 먼저 섀도(로그만), 이후 deny-by-default.
- 롤백 트리거: SLO 위반 시 짝 스냅샷 복원,
launchctl kickstart, doctor 재실행. - RCA: grep 체크리스트·티켓 갱신, 다음 카나리아 일정.
인용용 사실
- 관찰 창: 정책 편집 후 유지·롤백을 결정하기 전에 최소 5분 슬라이딩 창을 본다—기동 스파이크만으로는 사건이 아닙니다.
- 스냅샷 보존: 프로덕션에서 복원 가능한 설정 리비전을 3개 유지하고 각각에 플러그인 tarball 체크섬을 붙입니다.
- 감사 보존: 전체 doctor 출력과 grep 캡처를 티켓에 30일 이상 붙여 내부 컴플라이언스 샘플 점검에 대비합니다.
FAQ
manifest에 capability를 적었는데 왜 「미선언」인가요?
doctor가 출력하는 해석 경로와 편집한 파일을 대조하세요. 스키마 버전·필드 대소문자를 확인하고, 필요하면 스테이징에서 전체 로드 로그로 재현합니다.
dispatch를 끈 뒤에도 옛 세션이 플러그인을 부르나요?
큐와 구현에 따라 다릅니다. 리로드하고 SLO가 허용하면 미확인 작업을 버리고, 읽기 전용 스모크로 중요 경로를 확인하세요.
fail-closed와 섀도 모드는 공존할 수 있나요?
가능합니다. 섀도는 HTTP 상태를 바꾸지 않고 「거부됐을 것」 카운터만 올립니다. 곡선이 평탄해지면 하드 거부로 승격하세요.
요약과 Mac mini가 이 부하에 맞는 이유
플러그인 거버넌스는 부족한 구두 지식을 기계로 검증 가능한 정책으로 옮깁니다: manifest가 capability를 묶고, fail-closed가 실패 자세를 정하고, ACP dispatch가 인입 표면을 줄이며, doctor와 grep이 감사자가 기대하는 증거 사슬을 제공합니다.
macOS에서는 launchd, Unified Logging, Gatekeeper, SIP와 잘 맞물립니다. Apple Silicon Mac mini M4는 대기 전력이 대략 4W 수준이라 상시 게이트웨이와 옆구리 프로브에 적합하고, 같은 가격대 범용 미니 PC와 비교해 OpenClaw·헬스 익스포터·가벼운 CI 러너를 한 대의 원격 물리 머신에 얹을 때 장시간 세션이 더 매끄러운 경우가 많습니다.
셀프 랙 대신 전용 호스팅 노드로 이 런북을 돌리고 싶다면 2026년에도 Mac mini M4는 비용 대비 강한 출발점입니다—원격 물리 Mac을 확보하고 manifest 강제와 롤백을 반복 가능한 절차로 만드세요.
OpenClaw 플러그인 거버넌스용 전용 원격 Mac이 필요하신가요?
manifest 강화·감사 가능한 롤백에 맞춘 Apple Silicon macOS 노드.