OpenClaw는 셀프호스팅 멀티채널 게이트웨이다. 공식 허브 docs.openclaw.ai는 한 줄로 Any OS gateway for AI agents across Discord, Google Chat, iMessage, Matrix, Microsoft Teams, Signal, Slack, Telegram, WhatsApp, Zalo 등으로 적는다. 한 Gateway 프로세스가 채널 플러그인과 WebChat, 모바일 노드를 받는다. 라이선스는 MIT다. 코딩 에이전트의 도구 사용, 세션, 메모리, 멀티에이전트 라우팅을 전제로 설계되어 있다.
권장 런타임은 Node 26이며, Node 22.22.3 이상도 문서에 적혀 있다. 런타임이 맞아도 기본 도구 세트가 읽기만 하는 것은 아니다. 기능 표를 전부 켜면 봇 토큰을 가진 사람과 그룹 멤버가 셸, 파일, 외부 전송에 같이 닿는다.
공식 텔레그램 채널 문서는 기본 dmPolicy를 pairing으로 두고, 페어링 코드는 1시간 뒤 만료된다고 적는다. 승인 전에는 메시지가 에이전트 루프로 들어가지 않는다. 그 정책은 채널 입구의 최소값이지, 디렉터리 읽기나 명령 실행, 외부 전송의 상한이 아니다. allowFrom과 그룹 ID는 누가 말할 수 있는지를 가르고, 말한 뒤의 실행은 읽기, 쓰기, 금지 세 문장이 가른다.
MCP나 외부 도구를 추가하면 반환 텍스트가 메모리, 스킬, 채널 중 어디에 저장되는지가 범위에 들어간다. 권한을 여는 순서는 읽기 전용과 요약, 실패·예산 알림, 제한된 경로 쓰기, 외부 채널이다. 한 단계가 관측되지 않으면 다음이 열리지 않는 구성이 원인 분석에 유리하다.

Gateway 프로세스
OpenClaw의 본체는 채널에서 온 메시지를 에이전트에 넘기고, 응답을 다시 채널로 보내는 게이트웨이다. 프로세스가 하나이므로 Discord와 Telegram이 같은 실행 층을 공유한다. 채널을 늘리는 일은 입구를 넓히는 일이고, 실행 범위를 잠그는 일이 아니다.
게이트웨이를 띄우는 명령은 openclaw gateway다. 텔레그램은 토큰을 넣은 뒤 이 명령을 돌린다. openclaw channels login telegram은 쓰지 않는다. Control UI 기본은 127.0.0.1:18789 루프백이다. 그 주소는 그 컴퓨터 안에서만 통한다. Mini App /dashboard는 HTTPS 공개 URL과 숫자 사용자 ID owner 검사가 필요하고, 그룹이 아니라 DM에서만 버튼이 나온다. gateway.tailscale.mode가 serve 또는 funnel일 때 Mini App URL이 생긴다.
게이트웨이가 살아 있는 것은 원격의 전제다. 채널만 살고 프로세스가 죽으면 승인은 근거가 없다. 사람 옆에서는 잘못된 쓰기를 바로 되돌릴 수 있다. 무인 구간에는 온콜이 없으면 밤에 끊을 사람이 없다. 데모에서 잘 된 권한 세트를 프로덕션에 복사하면, 사람 옆에서 돌던 도구가 밤새 같은 권한으로 남는다.
채널 텍스트는 두 번째 저장소다. 메신저 백업과 알림 미리보기에 승인 메시지가 남는다. API 키, env 조각, 고객 로그가 그 메시지에 있으면, 게이트웨이 로그와 별개의 복사본이 생긴다.
게이트웨이 프로세스가 하는 일은 메시지를 큐에 넣고, 세션을 고르고, 에이전트 응답을 다시 채널로 보내는 것이다. Discord 플러그인과 Telegram 플러그인이 같은 프로세스 안에 있으면, 한 쪽 채널의 쓰기 권한이 다른 쪽 입구로 새지 않게 채널별 정책이 필요하다. 정책이 없어도 실행 층은 하나다. 그래서 기능 표를 채널 수만큼 켜는 일이 사고면을 넓힌다. WebChat은 브라우저 입구이고, 모바일 노드는 폰 입구다. 둘 다 같은 Gateway PID 뒤에 붙는다. PID가 죽으면 모든 입구가 같이 죽는다. openclaw gateway가 그 PID를 띄우는 명령이다.
Control UI 루프백은 운영자가 그 컴퓨터에서 상태를 보는 화면이다. 원격 공개 URL이 생기면 입구가 하나 더 생긴다. Mini App은 그 URL을 텔레그램 WebApp으로 감싼 형태다. 서명이 봇 토큰에 묶이므로, 토큰이 새면 Mini App owner 검사도 같이 다시 잠근다.
Node 런타임
권장 런타임 Node 26과 Node 22.22.3 이상은 게이트웨이 프로세스를 띄우는 조건이다. 버전이 낮으면 프로세스가 안 뜨거나 플러그인이 깨질 수 있다. 버전이 맞아도 삭제와 결제, 프로덕션 배포, PII 발송이 도구 세트에 남아 있으면 채널 멤버가 그 도구에 닿는다.
MIT 라이선스는 코드를 직접 돌린다는 전제다. 전제는 책임의 위치이지 오늘 허용의 상한이 아니다. Hermes Agent도 셀프호스트 오픈소스이고 메신저 게이트웨이가 있으나, 그 제품의 실행 루프와 터미널 백엔드는 비교 문서의 층이다.
Node 버전은 플러그인 로더가 기대하는 언어 런타임이다. 22.22.3 미만이면 게이트웨이가 기동 중에 멈추거나, 채널 패키지가 native 의존성에서 깨질 수 있다. 26 권장은 그 시점 문서의 기본 개발 버전이다. 런타임을 올린 뒤에야 dmPolicy와 allowFrom이 의미를 갖는다. 버전이 맞아도 도구 세트가 삭제를 포함하면 채널 멤버가 그 도구에 닿는다. 런타임 점검과 권한 점검은 다른 층이다.
openclaw doctor는 설정 검증이다. allowlist인데 allowFrom이 비면 검증이 거절한다. 예전 @username 항목을 숫자 ID로 바꾸려는 --fix도 이 명령에 있다. 페어링 저장소 시절 허용 목록을 channels.telegram.allowFrom으로 옮기는 경로가 문서에 있다. 그룹 발신자 인증은 그 저장소를 상속하지 않는다.
Docker로 게이트웨이를 돌리는 구성에서 Mini App의 Serve/Funnel은 루프백 옆의 tailscaled이 필요하다. 브리지 네트워크에 포트만 열면 그 조건이 안 맞는다. 문서가 적는 패턴은 network_mode: host와 호스트 tailscaled 소켓(/var/run/tailscale) 마운트다.
dmPolicy pairing
channels.telegram.dmPolicy는 다이렉트 메시지 접근을 가른다. 값은 pairing(기본), allowlist, open이다. allowlist는 allowFrom에 발신자 ID가 하나 이상 있어야 한다. open은 allowFrom에 "*"가 있어야 한다.
기본 pairing에서는 봇에 처음 메시지를 보내면 페어링 코드가 나온다. 서버에서 승인하기 전에는 메시지가 에이전트 루프로 들어가지 않는다. 문서 기준 코드는 1시간 만료다. 코드는 8자 대문자이고, 혼동 문자(0O1I)를 빼며, 채널 계정당 대기 요청은 3개로 막힌다. 추가 요청은 하나가 만료되거나 승인될 때까지 무시된다. 봇은 발신자당 대략 한 시간에 한 번 페어링 메시지를 보낸다.
승인은 서버 콘솔에서 돈다.
openclaw pairing list telegram
openclaw pairing approve telegram <CODE>
pairing list는 대기 중인 코드를 보여 준다. pairing approve는 그 발신자에게 DM 접근을 연다. 첫 승인에서 아직 command owner가 없으면 commands.ownerAllowFrom을 그 발신자로 부트스트랩한다. 이후 승인은 DM 접근만 주고 owner를 넓히지 않는다.
pairing 승인은 「이 사람이 모든 곳에서 관리자」가 아니다. DM 접근과 그룹 allowlist, owner 부트스트랩은 다른 축이다. 그룹 발신자 인증은 페어링 저장소를 상속하지 않는다. 문서가 보안 경계로 적은 시점 표기는 2026.2.25다.
dmPolicy: open에 allowFrom: ['*']를 넣으면 봇 사용자 이름을 아는 모든 텔레그램 계정이 명령을 보낸다. 고의로 공개 봇을 만들고 도구를 강하게 잠근 경우가 아니면 숫자 사용자 ID allowlist가 맞다. allowlist인데 allowFrom이 비면 모든 DM이 거부되고 설정 검증이 거절한다. 예전 @username 항목은 openclaw doctor --fix가 숫자 ID로 바꾸려 시도한다.
allowFrom과 그룹 ID
그룹에 봇을 넣은 뒤 필요한 값은 두 가지다. 자신의 텔레그램 사용자 ID는 allowFrom / groupAllowFrom에 둔다. 그룹 채팅 ID는 channels.telegram.groups 키로 둔다. 슈퍼그룹 ID는 -100으로 시작하는 음수다. 그 값은 groupAllowFrom이 아니라 groups 아래 키로 간다.
groupAllowFrom이 비면 텔레그램은 allowFrom으로 떨어진다. 페어링 저장소로는 떨어지지 않는다. 한 사람 봇의 실무 패턴은 사용자 ID를 allowFrom에 두고 groupAllowFrom은 비우며, 대상 그룹만 groups 아래에 허용하는 쪽이다.
설정 예는 아래 형태다.
{
channels: {
telegram: {
enabled: true,
botToken: "123:abc",
dmPolicy: "pairing",
allowFrom: ["<YOUR_TELEGRAM_USER_ID>"],
groups: { "*": { requireMention: true } },
},
},
}
환경 변수 폴백은 TELEGRAM_BOT_TOKEN(기본 계정만)이다. named account는 botToken 또는 tokenFile을 쓴다. 토큰 해석 순서는 tokenFile이 botToken보다, 설정이 env보다 앞선다. tokenFile은 일반 파일이어야 하고, 심볼릭 링크는 거절된다. 기동 후 봇 identity를 최대 24시간 캐시하므로, 토큰을 바꾸거나 지우면 그 캐시도 비운다.
그룹은 기본으로 멘션이 필요하다. 봇 핸들이 에이전트 페르소나 이름과 달라도, 그 핸들 멘션은 선택된 에이전트를 가리킨다. 멘션 요구는 입구의 필터이지, 도구 권한의 상한이 아니다. 텔레그램 봇 기본 Privacy Mode는 그룹 메시지 수신을 제한한다. 모든 그룹 메시지를 보려면 BotFather /setprivacy로 끄거나 봇을 그룹 관리자로 둔다. 토글 뒤에는 그룹에서 봇을 뺐다가 다시 넣어야 적용된다. 관리자 봇은 모든 그룹 메시지를 받으므로, 그 권한과 도구 범위를 같이 좁히는 구성이 사고면을 줄인다.
/whoami@<bot_username>은 사용자와 그룹 ID를 확인하는 경로다. 그룹 채팅 ID는 openclaw logs --follow, 전달 ID 봇, Bot API getUpdates에서도 나온다.
읽기 쓰기 금지
공식 기능 표는 가능한 일의 목록이다. 오늘 허용은 읽기 경로, 실행 가능한 명령, 외부로 나갈 내용 세 문장이다. 세 문장이 비면 데모 성공이 곧 권한 확장이 된다. 텔레그램 allowFrom과 그룹 키는 누가 말할 수 있는지만 가른다. 말한 뒤에 에이전트가 무엇을 실행하는지는 별도 설정이다.
범위 문장 예시는 아래와 같다. 오늘 이 에이전트는 {경로}를 읽고, {명령 집합}만 실행하며, {채널}로는 승인 요청만 보낸다. 금지: 삭제, 결제, 프로덕션 배포.
| 범위 | 예 | 실패 시 |
|---|---|---|
| 읽기 | 로그 요약, 테스트 실패 묶기 | 저장소 불변 |
| 제한 쓰기 | 지정 경로 초안, 스테이징만 | 그 경로만 되돌림 |
| 금지 | 삭제, 결제, 프로덕션 배포, PII 발송 | 사고면이 채널까지 퍼짐 |
핵심 포인트: 공식 기능 표는 가능한 일의 목록이다. 오늘 허용의 내용은 읽기 경로, 실행 가능한 명령, 외부로 나갈 내용 세 문장이다. 세 문장이 비면 데모 성공이 곧 권한 확장이 된다.
읽기 작업으로 시작했는데 쓰기로 번지는 경로는 「요약이 틀려서 파일을 고치게 시킴」이다. 요약이 틀리면 입력을 보강하거나 사람이 고친다. 틀렸다고 쓰기 권한을 주는 순간 범위 문장은 장식이 된다. 권한으로 품질을 사지 않는 이유가 이 경로다.
보류 목록이 세 개를 넘으면 이번 주 허용 문장을 다시 쓰는 편이 범위 유지에 가깝다. 목록이 늘어나는 것은 호기심이 아니라 범위가 무너지는 신호다. 끄지 못한 통합이 있으면 새로 열지 않는 쪽이 사고면을 늘리지 않는다.
읽기 범위의 실패는 저장소가 바뀌지 않는다. 제한 쓰기의 실패는 지정 경로만 되돌리면 된다. 금지 범위의 실패는 사고면이 채널까지 퍼진다. 세 층의 차이는 기능 이름의 화려함이 아니라 실패 시 남는 상태다.
MCP
Model Context Protocol은 외부 도구를 에이전트에 붙이는 규약이다. OpenClaw에 MCP를 추가하면 도구가 반환하는 텍스트가 메모리, 스킬, 채널 중 어디에 저장되는지가 같이 남는다. 자동 저장이면 시크릿 검사 규칙이 같은 변경에 들어간다. 도구 추가와 저장 정책을 한 커밋처럼 묶지 않으면 나중에 끄기 어렵다.
새 MCP의 실패 시 남는 권한 한 줄과, 끄려면 닫을 설정 경로 한 줄이 도구 이름보다 오래간다. 형식 오류를 재시도로 메우면 비용만 올라가고 범위 문장은 그대로다. 도구 호출 형식 오류가 많으면 반환 저장 위치부터 본다.
MCP 명세가 출처에 있는 이유는 외부 도구 반환 텍스트의 저장 위치가 범위 문장의 세 번째 칸(외부로 나갈 내용)과 맞닿기 때문이다. OWASP LLM Top 10은 시크릿과 도구 권한을 기능 표와 같은 층으로 읽지 말라는 쪽에 가깝다.
MCP 서버를 추가하면 에이전트가 그 서버의 도구 이름을 호출한다. 반환은 문자열이다. 그 문자열이 메모리에 자동 저장되면 다음 턴의 프롬프트가 된다. 채널로 다시 보내면 메신저 백업이 두 번째 복사본이 된다. 스킬 파일에 붙이면 디스크에 남는다. 세 위치 중 어디인지를 도구 이름과 같은 변경에 적지 않으면, 나중에 끄려 해도 검색 경로가 없다. 형식 오류가 많으면 스키마와 저장 위치가 먼저다. 재시도는 비용을 올리고 권한을 바꾸지 않는다. 도구 추가 커밋에 끄기 경로 한 줄이 없으면 그 도구는 사실상 상시 허용이다. 이름보다 저장 위치와 끄기 경로가 범위 문장에 남는다. 자동 저장이면 시크릿 검사가 같은 변경에 들어간다. 검사가 없으면 키가 다음 턴의 입력이 된다. 채널 백업과 메모리와 스킬 파일이 세 복사본이다.

권한 단계
한 번에 여러 통합을 켜면 어떤 변경이 사고를 냈는지 가르기 어렵다. 순서는 읽기 전용과 요약, 실패와 예산 알림, 제한된 경로 쓰기, 외부 채널이다.
| 단계 | 여는 것 | 확인 |
|---|---|---|
| 1 | 읽기 전용과 요약 | 산출물이 저장소를 안 바꿈 |
| 2 | 실패·예산 알림 | 의도적 실패에 알림이 옴 |
| 3 | 제한된 경로 쓰기 | 금지 목록이 설정에 반영됨 |
| 4 | 외부 채널 | 서버 콘솔에서 같은 작업을 끊을 수 있음 |
관측 없이 쓰기와 외부 채널을 같이 열면 사고 원인이 채널과 도구와 모델 사이에 섞인다. 최소 관측은 실패율, 지연, 비용, 인증 실패다. 성공 로그만 보이면 감시가 죽은 줄 모른다. 의도적 실패 한 번에 알림이 오지 않으면, 2단계가 끝나지 않은 상태다.
4단계의 「서버 콘솔에서 같은 작업을 끊을 수 있음」은 원격의 전제다. 외부 채널이 편할수록 콘솔 중단 경로가 같은 페이지에 있는지가 앞선다. 온콜이 없으면 밤에 끊을 사람이 없으므로, 무인 구간의 쓰기는 3단계의 지정 경로보다 더 좁아진다.
금지 목록이 설정에 반영되지 않은 채 3단계로 가면, 제한된 경로 쓰기가 사실상 열린 쓰기다. 삭제와 결제, 프로덕션 배포, PII 발송이 목록에만 있고 런타임에 없으면 문장은 장식이다.
Hermes 쪽과 자리를 나눌 때도 같은 단계가 유효하다. 입구만 OpenClaw에 두고 실행은 다른 층에 두면, 4단계의 외부 채널이 알림만 담당한다. 한 제품에 입구와 실행과 쓰기를 몰면 단계 표의 확인 열이 한 로그에 섞인다.
웹훅을 쓰는 구성은 공개 URL과 네트워크 경로가 추가로 생긴다. 기본 롱 폴링은 그 경로가 없다. 전송 방식의 선택은 지연과 방화벽의 문제이고, 페어링 정책의 대체재가 아니다. 웹훅이 켜져 있어도 미승인 DM은 pairing이 막는다. pairing이 열려 있어도 실행 범위 세 문장이 비면 승인된 한 줄이 도구 세트를 부른다.
입구와 실행 축
입구가 가리는 것과 실행 범위가 가리는 것은 한 표로 보면 축이 갈린다.
| 축 | 입구가 가르는 것 | 실행 범위가 가르는 것 |
|---|---|---|
| pairing | 미승인 DM | 디렉터리와 명령은 가리지 않음 |
| allowFrom, groupAllowFrom | 누가 말할 수 있는가 | 말한 뒤의 도구 세트는 가리지 않음 |
| 멘션 요구 | 멘션 없이 온 명령이 처리되는가 | 처리된 명령의 쓰기 권한은 가리지 않음 |
| 세 문장 | 해당 없음 | 읽기 경로, 명령, 외부 전송 |
| 금지 목록 | 해당 없음 | 삭제, 결제, 프로덕션 배포, PII 발송 |
BotFather 토큰은 봇의 신원이다. 토큰과 allowFrom과 도구 권한이 한 채팅에 붙어 있으면 유출 한 번에 입구와 실행이 같이 열린다. 승인 메시지에 남는 칸이 저장소 이름, 변경 요약 한 줄, 위험도(읽기/쓰기), 만료 시각이면, 미리보기에 경로와 키가 남는 폭이 줄어든다.
산출 품질 지표
체감으로 좋다는 문장은 교체 근거가 아니다. 사람이 되돌린 변경 비율, 같은 과제를 다시 실행했을 때 결과 변동, 도구 호출 형식 오류 횟수, 예산 대비 유용한 완료 작업 수를 본다. 네 숫자는 통합 이름보다 오래간다. 메뉴 라벨은 버전마다 바뀐다.
되돌림 비율이 높으면 통합을 더 사지 않는 편이 범위 유지에 가깝다. 입력 패킷(로그, 재현 단계, 관련 파일)이 부족한 경우가 많다. 한도 발동이 잦으면 범위가 넓거나 루프가 있다.
결과 변동이 크면 같은 읽기 과제를 두 번 돌리는 비교가 먼저다. 변동의 원인이 모델인지, 도구 스키마인지, 입력 패킷인지는 쓰기 개방 전에 갈린다.
오늘 확인하면 충분한 상태는 범위 문장이 팀 채널에 있고, 실험 키에 hard limit이 걸려 있으며, 의도적 실패 알림이 한 번이라도 왔고, 금지 목록에 삭제와 결제가 명시된 경우다. 네 조건은 기능 표의 체크와 다르다. 기능 표는 가능한 일을 나열하고, 네 조건은 오늘 허용이 운영 가능한지를 가른다.

버전별 메뉴 전체 나열과 버튼 클릭 순서는 범위 밖이다. 오늘 허용 세 문장, 금지 목록, 단계적 개방, 품질 지표가 본론이다. 라벨은 설정 직전 공식 채널 문서가 기준이다.
롱 폴링과 웹훅
OpenClaw 텔레그램의 기본 전송은 롱 폴링이다. 게이트웨이 프로세스가 Telegram Bot API에 업데이트를 묻고, 메시지가 오면 에이전트에 넘긴다. 공개 URL이 필요 없어서 방화벽이 단순한 환경에 맞다. 웹훅은 선택이다. 웹훅을 켜면 텔레그램이 지정한 HTTPS URL로 업데이트를 밀어 넣는다. 공개 URL과 인증서, 네트워크 경로가 추가로 생긴다. 집 밖 LTE에서 DNS와 절전이 달라지면 웹훅이 늦게 도착할 수 있다.
전송 방식은 pairing을 대체하지 않는다. 웹훅이 켜져 있어도 미승인 DM은 pairing이 막는다. pairing이 열려 있어도 실행 범위 세 문장이 비면 승인된 한 줄이 도구 세트를 부른다. getMe returned 401은 토큰이 틀린 상태다. OpenClaw는 폴링을 시작하기 전에 멈추므로, 웹훅 정리 실패로 보이지 않는다.
토큰을 바꾼 뒤에도 봇 identity 캐시가 최대 24시간 남아 getMe를 건너뛸 수 있다. 폐기한 토큰과 새 토큰이 한동안 섞여 보이면 그 캐시를 비운 상태인지가 먼저다. tokenFile이 심볼릭 링크면 거절된다. 일반 파일만 받는다.
Control UI와 Mini App
Control UI 기본은 127.0.0.1:18789 루프백이다. 그 컴퓨터 안의 브라우저만 닿는다. 원격에서 같은 화면을 열려면 Tailscale serve 또는 funnel이 별 경로로 HTTPS URL을 만든다. Mini App /dashboard는 그 URL이 있어야 버튼이 나온다. 그룹에서 /dashboard를 치면 open this in a DM with the bot만 돌아오고 버튼은 없다.
Mini App owner는 숫자 텔레그램 사용자 ID가 allowFrom 또는 commands.ownerAllowFrom에 있어야 한다. 와일드카드와 사용자 이름은 owner를 주지 않는다. 텔레그램이 넘기는 WebApp initData는 봇 토큰으로 서명을 검증한다. 없거나 만료됐거나 재사용된 데이터는 거절된 뒤에 사용자 ID를 꺼내고, owner를 한 번 더 본 다음 Control UI로 넘긴다.
Docker에서 Serve/Funnel은 게이트웨이가 tailscaled 옆 루프백에 붙어야 한다. 브리지 네트워크에 포트만 열면 그 조건이 안 맞는다. 문서 패턴은 network_mode: host와 호스트 /var/run/tailscale 소켓, tailscale CLI 마운트다.
/whoami@<bot_username>은 사용자와 그룹 ID를 확인하는 경로다. 그룹 채팅 ID는 openclaw logs --follow, 전달 ID 봇, Bot API getUpdates에서도 나온다. -100으로 시작하는 값은 groups 키로 가고 groupAllowFrom으로 가지 않는다.
allowFrom은 숫자 ID를 받는다. telegram:과 tg: 접두는 정규화된다. 다중 계정에서 상위 channels.telegram.allowFrom이 좁으면, 계정 단위 allowFrom: ["*"]만으로 공개 봇이 되지 않는다. 합쳐진 유효 allowlist에 와일드카드가 명시되어 있어야 한다. 계정이 둘 이상이면 channels.telegram.defaultAccount를 두는 편이 라우팅을 분명하게 한다. 생략하면 첫 정규화 계정 ID로 떨어지고 openclaw doctor가 경고한다.
Gateway 한 프로세스가 Discord부터 Zalo까지 받는다는 공식 한 줄은 입구의 폭이다. WebChat과 모바일 노드가 같은 프로세스에 붙는다는 문장도 입구 쪽이다. 코딩 에이전트의 도구 사용, 세션, 메모리, 멀티에이전트 라우팅은 게이트웨이가 전제로 두는 실행 층이다. 전제가 있다고 해서 설치 직후 실행 범위가 읽기만인 것은 아니다. Node 26 권장과 Node 22.22.3 이상은 프로세스를 띄우는 조건일 뿐이다.
읽기 범위의 예는 로그 요약과 테스트 실패 묶기다. 제한 쓰기의 예는 지정 경로 초안과 스테이징이다. 금지의 예는 삭제, 결제, 프로덕션 배포, PII가 섞인 메일과 채팅 발송이다. 데모에서 잘 된 권한 세트를 프로덕션에 복사하면 사람 옆에서 돌던 도구가 밤새 같은 권한으로 남는다. 무인 구간에는 온콜이 없으면 밤에 끊을 사람이 없다.
MCP 도구가 반환하는 텍스트가 메모리에 자동 저장되면, 시크릿 검사가 도구 추가와 같은 변경에 들어가지 않는 한 나중에 끄기 어렵다. 끄려면 닫을 설정 경로 한 줄과, 실패 시 남는 권한 한 줄이 도구 이름보다 오래간다. 형식 오류를 재시도로 메우면 비용만 올라간다.
오늘 허용 세 문장의 빈칸은 디렉터리, 명령, 외부 전송이다. 예시 문장 틀은 오늘 이 에이전트는 {경로}를 읽고, {명령 집합}만 실행하며, {채널}로는 승인 요청만 보낸다. 금지: 삭제, 결제, 프로덕션 배포.다. 세 문장이 팀 채널에 있고, 실험 키에 hard limit이 걸려 있으며, 의도적 실패 알림이 한 번이라도 왔고, 금지 목록에 삭제와 결제가 명시된 상태가 운영 가능한 최소치다.
tokenFile과 botToken
텔레그램 봇 신원은 세 곳에 올 수 있다. OpenClaw는 tokenFile이 botToken보다 앞선다. 설정 파일의 값이 환경 변수 TELEGRAM_BOT_TOKEN보다 앞선다. named account는 env 폴백을 쓰지 않고 botToken 또는 tokenFile을 둔다. 우선순위가 이렇게 고정돼 있으므로, 파일만 바꾸고 env를 옛값으로 두면 새 토큰이 안 먹힌다.
tokenFile은 일반 파일이어야 한다. 심볼릭 링크는 거절된다. 거절 이유는 링크 대상이 바뀌어도 설정 문자열이 같아 보여서, 어떤 비밀이 로드됐는지 로그로 가르기 어렵기 때문이다. 파일 권한은 게이트웨이 프로세스를 도는 OS 사용자만 읽게 두는 편이 사고면을 줄인다. 채팅에 토큰을 붙여 넣으면 파일 분리가 무의미해진다. BotFather가 재발급한 뒤에는 세 위치와 identity 캐시를 같이 비운다.
getMe returned 401은 텔레그램이 설정된 토큰을 거절했다는 뜻이다. OpenClaw는 폴링을 시작하기 전에 이 응답에서 멈춘다. 웹훅 정리 실패로 보이지 않는다. 토큰을 고친 뒤에도 봇 identity 캐시가 최대 24시간 남아 getMe를 건너뛸 수 있다. 폐기한 토큰과 새 토큰이 한동안 섞여 보이면 그 캐시를 비운 상태인지가 먼저다.
웹훅을 쓰는 구성은 공개 HTTPS URL이 추가로 생긴다. 기본 롱 폴링은 그 URL이 없다. 전송 방식은 pairing을 대체하지 않는다. 웹훅이 켜져 있어도 미승인 DM은 pairing이 막는다. pairing이 열려 있어도 실행 범위 세 문장이 비면 승인된 한 줄이 도구 세트를 부른다.
세션과 메모리
게이트웨이가 채널 메시지를 에이전트에 넘기면, 그 턴의 세션이 도구 호출을 쌓는다. 세션이 길면 컨텍스트가 도구 결과로 채워진다. 메모리가 자동 저장이면 MCP 반환과 채널 텍스트가 다음 턴의 입력이 된다. 시크릿 검사가 그 저장 경로에 없으면, 한 번 새어 들어간 키가 세션을 넘어 남는다.
WebChat은 브라우저 입구이고 모바일 노드는 폰 입구다. 둘 다 같은 Gateway PID 뒤에 붙는다. PID가 죽으면 모든 입구가 같이 죽는다. openclaw gateway가 그 PID를 띄운다. Control UI 127.0.0.1:18789는 같은 프로세스의 운영 화면이다. 루프백이므로 그 컴퓨터 밖의 브라우저는 닿지 않는다. Tailscale serve나 funnel이 HTTPS URL을 만들면 Mini App /dashboard 버튼이 그 URL을 연다.
그룹에서 /dashboard를 치면 open this in a DM with the bot만 돌아오고 버튼은 없다. Mini App owner는 숫자 텔레그램 사용자 ID가 allowFrom 또는 commands.ownerAllowFrom에 있어야 한다. 와일드카드와 사용자 이름은 owner를 주지 않는다. 텔레그램 WebApp initData는 봇 토큰으로 서명을 검증한다. 토큰이 새면 Mini App owner 검사도 같이 다시 잠근다.
Discord 플러그인과 Telegram 플러그인이 같은 프로세스에 있으면, 한 쪽 채널의 쓰기 권한이 다른 쪽 입구로 새지 않게 채널별 정책이 필요하다. 정책이 없어도 실행 층은 하나다. 기능 표를 채널 수만큼 켜는 일이 사고면을 넓히는 이유다. 끄지 못한 통합이 있으면 새로 열지 않는 쪽이 범위를 유지한다.
openclaw pairing list telegram은 대기 중인 8자 코드를 보여 준다. openclaw pairing approve telegram <CODE>는 그 발신자에게 DM 접근을 연다. 첫 승인에서 아직 command owner가 없으면 commands.ownerAllowFrom을 그 발신자로 부트스트랩한다. 이후 승인은 DM 접근만 주고 owner를 넓히지 않는다. 그룹 권한은 별도 allowlist다. pairing 승인은 그 사람이 모든 곳에서 관리자라는 뜻이 아니다.
dmPolicy 값 pairing은 기본이다. allowlist는 allowFrom에 발신자 ID가 하나 이상 있어야 한다. open은 allowFrom에 "*"가 있어야 한다. 코드는 1시간 만료, 8자 대문자, 0O1I 제외, 계정당 대기 3개다. 봇은 발신자당 대략 한 시간에 한 번 페어링 메시지를 보낸다. /whoami@<bot_username>은 사용자와 그룹 ID를 돌려준다. -100으로 시작하는 슈퍼그룹 ID는 groups 키로 가고 groupAllowFrom으로 가지 않는다.
마무리
앞에서 다룬 OpenClaw 작업 범위의 핵심만 짧게 정리한다.
- OpenClaw는 채널을 코딩 에이전트에 연결하는 셀프호스트 게이트웨이다.
- 권장 런타임은 Node 26이고, Node 22.22.3 이상도 문서에 적혀 있다.
- 텔레그램 기본 dmPolicy는 pairing이고, 페어링 코드는 1시간 만료다.
- allowFrom과 그룹 ID는 누가 말하는지를 가른다. 말한 뒤의 실행은 세 문장이다.
- 첫 범위는 저장소가 바뀌지 않는 읽기와 요약, 알림이다.
- MCP 반환이 메모리나 채널에 자동 저장되면 시크릿 검사가 같은 변경에 들어간다.
- 관측 없이 쓰기와 채널을 같이 열면 원인 분석이 섞인다.
「기능 표가 아니라 오늘 허용 세 문장이 OpenClaw 범위다.」 통합 이름보다 읽기 경로, 명령, 외부 전송이 먼저 고정된다. 설정 직전 공식 채널 문서와 화면을 대조하는 일이 라벨 변경을 따라잡는 방법이다.
출처와 링크
- OpenClaw 공식 허브: https://docs.openclaw.ai/
- OpenClaw 텔레그램 채널: https://docs.openclaw.ai/channels/telegram
- OpenClaw pairing: https://docs.openclaw.ai/channels/pairing
- Hermes Agent 문서: https://hermes-agent.nousresearch.com/docs/
- Model Context Protocol: https://modelcontextprotocol.io/
- OWASP Top 10 for LLM Apps: https://owasp.org/www-project-top-10-for-large-language-model-applications/
조사 기준: 2026년 8월. 페어링 만료와 dmPolicy 기본값은 설정 직전 공식 채널 문서가 기준이다.