테스트만 초록이다: CopilotKit OpenBot이 판 감사 로그
CopilotKit가 공개한 OpenBot은 자체 인프라에서 동작마다 결정을 내리고 감사 로그를 남기는 오픈소스 엔터프라이즈 에이전트라고 한다. 리뷰어들이 연 이슈의 공통점은, 그 결정 함수가 테스트에는 있고 실행 게이트에는 없다는 것이다.
핵심 요약 (TL;DR)

CopilotKit OpenBot은 2026년 8월 17일 GitHub에 올라온 MIT 라이선스 저장소다. 배지는 알파, 첫 태그는 v0.0.1이다. 공식 사이트는 이를 자체 인프라에서 돌아가는 엔터프라이즈 에이전트 플랫폼이라고 판다. 에이전트는 사람 대신 도구를 호출하고 브라우저를 조작하는 실행 단위다. 봇마다 Docker 컨테이너와 작업 공간, Chromium을 주고, 게이트웨이가 동작을 실행 전에 결정하고 실행 후에 기록한다고 한다. 권한은 실패 시 닫힌다(fail-closed)는 문장도 제품 페이지에 있다.

그 문장은 단단하다. 구현은 테스트에서만 초록이다. 8월 20일 리뷰어들이 연 이슈들은 권한 검사가 정의되고 단위 테스트는 통과하는데 실행 경로에서 호출되지 않는다고 적는다. 경로 순회, 클라우드 메타데이터 서비스(인스턴스가 자기 자격 증명을 읽는 내부 주소) 차단의 구멍, 거부 규칙이 참·거짓이 아니면 조용히 허용되는 비대칭이 같은 주에 열려 있다. 유지보수자 본인이 며칠 전 머지한 문장이 이 글의 제목이다. 「기록은 제품이다. 위조할 수 있는 기록은 기록이 없는 것보다 나쁘다.」 알프다. 회사 로그인을 맡길 물건이 아니다.
배경 및 맥락
저장소 CopilotKit/OpenBot은 2026-08-17 00:44 UTC(한국 시간 같은 날 09:44)에 만들어졌다. openbot과 OpenBot은 같은 저장소다. 라이선스는 MIT. 같은 날 11:36 KST에 유지보수자 davidmckayv가 v0.0.1을 올렸다. 릴리스 노트는 노트북에서 돌아가며 모서리가 거칠고, 호스티드 배치는 아직 없다고 적는다. README 배지도 Alpha다.
공식 페이지 copilotkit.ai/openbot의 톤은 데모가 아니라 보안 검토다. 공유 테넌트가 없고, 문서·벡터·대화는 고객 Postgres에 남으며, 민감한 MCP 호출은 도구별 허용 목록과 기록을 거친다고 한다. MCP는 Model Context Protocol로, 에이전트가 외부 도구와 지식에 붙는 표준이다. Docker Compose는 데모, Helm이 프로덕션 경로라고 적혀 있다. 검색은 실패 시 닫히고, 권한 매핑이 애매하면 문서를 돌려주지 않는다고 한다.
Show HN은 그보다 제품 문장을 좁힌다. 2026-08-19 18:45 UTC(한국 시간 8월 20일 03:45), mikeryan52가 「open-source Grok Bot that works with any agent harness」로 올렸다. 하네스는 에이전트를 감싸 도구·정책·화면을 붙여 주는 틀이다. 공식 사이트는 Grok Bot이라는 단어를 쓰지 않는다. 점수는 12, 보이는 댓글은 유지보수자 davidmckayv의 한 줄이다. 알파고 로드맵이 많이 남았다는 안내였다.
실행 조건은 README가 분명히 한다. CopilotKit Intelligence 프로젝트와 라이선스, 모델 키가 필요하다. 기본값은 OPENBOT_DEV_NO_AUTH다. 로그인을 건너뛰고 모든 요청을 관리자 한 명으로 받는다. 아키텍처 문서는 이 값을 프로덕션(NODE_ENV=production)에서 거절한다고 적는다. Google 로그인을 켜면 최초 관리자 이메일만 관리자가 되고 나머지는 일반 사용자가 된다. 엔터프라이즈 주장은 그 전환 이후를 전제한다.
봇의 「컴퓨터」는 가상 머신이 아니다. Docker 컨테이너다. 안에 Chromium과 /workspace가 있다. COMPUTER_SUPERVISOR_URL이 있으면 슈퍼바이저가 봇마다 컨테이너를 만든다. 없으면 모든 봇이 공유 컴퓨터(AGENT_COMPUTER_URL)를 쓴다. 「봇마다 컴퓨터」는 설정이 있을 때의 문장이다. AG-UI 엔드포인트만 말하면 LangGraph, CrewAI, Mastra, Pydantic AI, Google ADK, 손수 짠 봇을 붙일 수 있다고 README는 적는다. 거버넌스는 프레임워크가 아니라 프로토콜을 탄다는 주장이다.
주요 내용 분석
주장 문장과 실행 경로
제품이 반복하는 골격은 짧다. 게이트웨이가 대상을 해석하고, 정책을 평가하고, 감사 행을 쓴 뒤에야 컴퓨터에 손댄다. 동작 없는 기록은 없고, 기록 없는 동작도 없다는 뜻이다. CEL 정책은 거부(deny)를 허용(allow)보다 먼저 보고, 정책이 없거나 깨지면 닫힌다고 README는 적는다. 공식 사이트도 검색과 MCP를 같은 방향으로 판다.

8월 20일 beardthelion이 연 이슈 #35는 그 골격의 한 칸이 비어 있다고 한다. canRunAgent는 정의되어 있고, 다른 사용자의 비공개 봇에 대해 거짓을 반환한다는 테스트도 초록이다. 실행 경로에서는 호출되지 않는다. 호출되는 쪽은 관리 권한 검사뿐이다. 봇 식별자를 요청에서 바로 받는 표면 — 컴퓨터 API, 플러그인 호출, 컴포넌트, 화면 스트림 — 의 문은 로그인 여부였다. 이슈의 주장은 이렇다. 일반 사용자 역할만으로 다른 사람 봇의 브라우저와 작업 공간, 부여된 MCP를 다룰 수 있다. 고치는 PR #37은 같은 날 열렸고, 이 글을 확인하는 시점에 아직 열려 있다. 머지되지 않았다.
같은 저자의 이슈 #29는 그 식별자가 파일 경로가 된다고 한다. 경로 순회가 이슈로 열려 있다. 이슈 본문이 같이 적어 둔 한계도 사실이다. 슈퍼바이저 쪽 이름 규칙(supervisor/src/names.ts)은 식별자를 제한하고, 작업 공간 도구는 이미 여러 겹으로 가둔다. 샌드박스 — 프로세스를 가둬 두는 격리 — 가 없는 것이 아니다. 프로필 경로를 만드는 한 곳이 그 규칙을 쓰지 않는다는 지적이다.
닫힌다고 쓴 주소
아키텍처 문서는 클라우드 메타데이터 주소를 모든 설정에서 거절한다고 적는다. 이슈 #36은 에이전트 주소 검사가 처음 한 칸만 보고, 그다음 연결은 리다이렉트를 따라간다고 한다. 검사가 끝난 주소와 실제로 닿는 주소가 같아지는 것은, 아무도 방향을 바꾸지 않을 때뿐이다. 이슈 #25는 같은 차단이 IPv6 표기를 놓친다고 한다. 둘 다 열려 있다. 재현 절차는 이 글에 적지 않는다. 이슈가 공개되어 있다.
이슈 #26은 정책 엔진의 비대칭이다. 거부 규칙이 참·거짓이 아닌 값을 내면 거부로 처리되지 않고, 기본 허용으로 넘어간다. 같은 표현이 허용 목록에 있으면 실패 시 막힌다. 문서와 주석은 깨진 표현이 닫힌다고 하는데, 닫히는 쪽은 예외가 던져질 때뿐이다. 운영자가 규칙을 저장하면 API는 200을 돌려주고, 목록에 살아 있는 것처럼 보인다.
목록 권한도 같은 패턴이다. kevin9327의 PR #45는 관리자 컴퓨터 페이지가 세션만 보고 전체 봇의 기계를 돌려준다고 한다. 비공개 봇의 식별자와 가동 여부까지 로그인 사용자에게 열린다는 주장이다. 아직 열려 있다. 같은 저자의 PR #46은 게이트웨이가 동작을 해석할 때 쓰는 스냅샷이 프로세스 안 메모리 Map이라고 한다. 서버가 둘이면 스냅샷을 찍은 쪽과 클릭을 받는 쪽이 갈라지고, 복제본은 정책을 보지 못한다. 거부는 흔들리고, 요소를 가리키지 않는 규칙은 조용히 통과한다. PR #21이 「아직 같은 문제가 있다」고 남겨 둔 캐시다.
| 이슈·PR | 주장 (요약) | 상태 | 성격 |
|---|---|---|---|
| #35 | 실행 권한 함수가 테스트에만 있고 실행 경로에서 호출되지 않는다 | 열림. 수정 PR #37도 열림 | 보안 |
| #29 | URL의 봇 식별자가 파일 경로가 되어 경로 순회가 가능하다 | 열림 | 보안 |
| #36 | 에이전트 주소 검사가 리다이렉트 너머를 보지 않는다 | 열림 | 보안 |
| #25 | 사설망·메타데이터 차단이 IPv6 표기를 놓친다 | 열림 | 보안 |
| #26 | 거부 규칙이 불리언이 아니면 조용히 허용한다. 허용 목록은 실패 시 닫힌다 | 열림 | 보안 |
| PR #45 | 로그인 사용자가 비공개 봇을 포함한 컴퓨터 목록을 본다 | 열림 | 보안 |
| PR #46 | 스냅샷이 프로세스 메모리라 복제본에서 정책이 보이지 않는다 | 열림 | 보안 |
| #39 / #42 | 봇 Dockerfile이 root로 뜬다 (CWE-250) | 닫힘. #42 머지 | 보안 |
| #12 / #13 | 동봉 봇이 OPENAI_BASE_URL을 무시한다 | 닫힘. #13 머지 | 구성 |
| #44, #47 | 채팅 크래시, 시스템 프롬프트 문단 붕괴 | 열림 | 품질. 보안 아님 |
| PR #34 | 공유 비밀과 요청 본문만으로 감사 주체를 쓸 수 있었다 | 머지 (8월 20일) | 보안. 유지보수자 |
| PR #21 | 한 대에서만 동작하는 승인 레지스터·반복 탐지를 되돌렸다 | 머지 (8월 20일) | 경계. 유지보수자 |
표의 아래 두 칸은 밖에서 온 공격 이슈가 아니다. 유지보수자가 스스로 거둬들인 기능과, 스스로 닫은 위조 경로다. 제품이 무엇을 두려워하는지가 드러난다.
유지보수자가 먼저 쓴 문장
davidmckayv의 PR #21은 승인 레지스트리(#15)와 반복 탐지(#17)를 되돌렸다. 둘 다 요청보다 오래 사는 상태를 서버 프로세스 안 Map에 두었다. 노트북에서는 맞고, 로드밸런서 뒤 두 번째 프로세스에서는 틀리다. 한 쪽에서 올린 질문이 다른 쪽에서 no longer open이 되고, 반복 횟수는 쪼개져 규칙이 발화하지 않는다. 둘 다 크게 실패하지 않는다. 그래서 고치기 전에 빼 냈다. 그가 쓴 문장이다. 「조용히 집행을 멈추는 경계는, 애초부터 광고하지 않은 경계보다 나쁘다. 그 배치가 그걸 믿고 있기 때문이다.」
같은 날 PR #34는 에이전트 도구 호출이 배포 전체 비밀 하나와 요청 본문의 봇·행위자 이름을 믿던 경로를 닫았다. 머지 시각은 2026-08-20 16:19 UTC. 본문 첫 줄이 이 제품의 자기 정의다. 「The trail is the product. A forgeable trail is worse than no trail, because it is believed.」 기록은 제품이다. 위조할 수 있는 기록은 기록이 없는 것보다 나쁘다. 믿기 때문이다. 새 설계는 에이전트마다 토큰을 주고, 한 번의 실행에만 유효한 서명을 맞춘다. 감사 행의 행위자는 본문이 아니라 그 서명에서 온다.
닫힌 이슈도 있다. begininvoke의 #39는 봇 Dockerfile에 USER가 없어 root로 뜬다고 했고, CWE-250을 붙였다. PR #42가 8월 20일 머지되며 닫혔다. knowhycodata의 #12는 동봉 봇이 OpenAI 호환 주소를 받지 못한다고 했고, PR #13이 8월 19일 머지됐다. 서버 쪽은 원래 OPENAI_BASE_URL을 읽었다. 컨테이너 안의 봇 두 개만 읽지 않았다. 구성 구멍이지 권한 구멍이 아니다. arpan7sarkar의 #44와 #47은 채팅이 죽고 시스템 프롬프트 문단이 한 줄로 붙는 품질 이슈다. 보안 목록에 넣지 않는다.
실사용자 반응
거의 없다. 이 글을 쓰는 2026-08-21 새벽(KST)은 Show HN 기준 하루가 채 되지 않았고, UTC 날짜로는 공개 이틀째다. Hacker News 점수 12, 보이는 댓글 1. 그 한 줄은 유지보수자다. 스레드에 죽은 항목이 하나 더 있으나 본문이 없고, 사용자 리뷰로 치지 않는다. 설치기, 실패기, 「우리 회사에 올려 봤다」는 글은 확인하지 못했다. GitHub API가 같은 시각에 돌려준 숫자는 스타 1,321, 포크 137, 열린 이슈 22다. 별은 관심이고, 댓글은 사용이 아니다. 관심과 사용을 같은 증거로 쓰지 않는다.
반응 대신 저장소 안 대화가 있다. 이슈를 연 쪽은 함수 이름과 테스트 파일과 실행 경로를 나란히 놓는다. 유지보수자 쪽은 한 대에서만 맞는 기능을 먼저 거둬들인다. 둘 다 제품의 자기 기준 — 기록, 경계, 실패 시 닫힘 — 을 기준으로 말한다. 사용자 후기가 없는 자리에서, 그 기준이 실행 경로에 연결됐는지만이 남아 있는 논쟁이다.
의미와 시사점
OpenBot이 판 것은 채팅 창이 아니다. 감사 로그다. 공식 문장은 보안 검토가 물을 답을 미리 써 두었다. 데이터가 어디에 있는가. 도구 호출이 누구의 자격 증명으로 나가는가. 거절된 동작이 기록에 남는가. 그 질문에 대한 답은 코드에 함수로 있다. 함수가 있는 것과 호출되는 것은 다른 일이다. #35의 테스트가 초록인 이유는, 규칙이 틀려서가 아니라 규칙이 문에 안 달려 있기 때문이다.
기본값 OPENBOT_DEV_NO_AUTH는 그 구멍을 노트북에서는 가린다. 모두가 이미 관리자다. 관리자면 #35의 「다른 봇을 다룬다」는 문장이 성립하지 않는다. 제품 페이지가 말하는 배치는 그게 아니다. Google 로그인을 켜고, 일반 사용자와 관리자를 나누고, Helm으로 여러 프로세스를 올리는 쪽이다. 그 배치에서 프로세스 안 Map은 경계를 조용히 끄고, 호출되지 않는 검사는 로그를 거짓으로 만든다. PR #34가 닫은 위조 경로와, 아직 열린 #35·#46은 같은 두려움의 앞뒤다. 믿기는 하는데 사실이 아닌 기록.
에이전트 플랫폼을 고를 때 「오픈소스라서 감사할 수 있다」는 문장은 반만 맞다. 저장소가 열려 있어 이슈 #35를 읽을 수 있는 것은 사실이다. 그 이슈가 가리키는 것은, 감사가 가능하다고 판 제품의 감사 문이 테스트 파일에 남아 있다는 점이다. 알파 배지는 변명이 아니라 분류다. 분류를 제품 페이지의 「엔터프라이즈」보다 먼저 읽어야 한다.
마치며
OpenBot은 봇마다 컨테이너를 주고, 게이트웨이를 유일한 입구로 두며, 기록을 제품이라고 부르는 실험이다. 그 문장을 유지보수자 본인이 가장 엄하게 적용하고 있다. 한 대에서만 집행되는 기능을 되돌렸고, 본문으로 주체를 쓰던 호출을 닫았다. 밖에서 온 이슈들은 같은 기준을 실행 경로에 대 보라고 한다. 대면, 테스트는 초록이고 문은 열려 있다. 알프다. 소스도 열려 있다. 회사 SSO를 붙이기 전에 읽을 이슈 번호는 이미 나와 있다. 초록은 테스트 러너에 두고, 로그인은 아직 주지 않는 편이 맞다.
출처
- 공식 사이트: https://www.copilotkit.ai/openbot
- 저장소: https://github.com/CopilotKit/OpenBot
- 릴리스 v0.0.1: https://github.com/CopilotKit/OpenBot/releases/tag/v0.0.1
- README: https://github.com/CopilotKit/OpenBot/blob/main/README.md
- 아키텍처 문서: https://github.com/CopilotKit/OpenBot/blob/main/docs/architecture.md
- Show HN (2026-08-19, 12 points, 댓글 1): https://news.ycombinator.com/item?id=49365575
- 이슈 #35 (beardthelion, 열림): https://github.com/CopilotKit/OpenBot/issues/35
- 이슈 #29 (beardthelion, 열림): https://github.com/CopilotKit/OpenBot/issues/29
- 이슈 #36 (beardthelion, 열림): https://github.com/CopilotKit/OpenBot/issues/36
- 이슈 #25 (beardthelion, 열림): https://github.com/CopilotKit/OpenBot/issues/25
- 이슈 #26 (beardthelion, 열림): https://github.com/CopilotKit/OpenBot/issues/26
- PR #45 (kevin9327, 열림): https://github.com/CopilotKit/OpenBot/pull/45
- PR #46 (kevin9327, 열림): https://github.com/CopilotKit/OpenBot/pull/46
- 이슈 #39 / PR #42 (머지): https://github.com/CopilotKit/OpenBot/issues/39, https://github.com/CopilotKit/OpenBot/pull/42
- 이슈 #12 / PR #13 (머지): https://github.com/CopilotKit/OpenBot/issues/12, https://github.com/CopilotKit/OpenBot/pull/13
- 이슈 #44, #47 (품질): https://github.com/CopilotKit/OpenBot/issues/44, https://github.com/CopilotKit/OpenBot/issues/47
- PR #34 (davidmckayv, 머지): https://github.com/CopilotKit/OpenBot/pull/34
- PR #21 (davidmckayv, 머지): https://github.com/CopilotKit/OpenBot/pull/21
- PR #37 (#35 수정, 열림): https://github.com/CopilotKit/OpenBot/pull/37
이 글은 AI가 작성하여 자동 발행된 콘텐츠입니다.