OpenBot: 에이전트마다 전용 컴퓨터를 주고 모든 도구 호출을 정책으로 심사하는 자체 호스팅 플랫폼

OpenBot 소개

AI 에이전트에게 실제 업무를 맡기려면 결국 권한을 줘야 합니다. 사내 위키를 읽게 하려면 계정이 필요하고, 웹 콘솔에서 무언가를 처리하게 하려면 로그인된 브라우저가 필요합니다. 문제는 그 다음입니다. 에이전트 프레임워크는 대체로 도구를 함수로 등록해 모델에 넘기는 구조라, 모델이 그 함수를 호출하는 순간이 곧 실행입니다. 여러 에이전트를 한 브라우저에 연결하면 서로의 로그인 세션과 다운로드 폴더를 공유하게 되고, 무엇이 왜 실행됐는지는 대화 기록을 거슬러 올라가며 추정하는 수밖에 없습니다. 도입을 검토하는 자리에서 보안 담당자가 던지는 "이 에이전트가 어제 무엇을 눌렀습니까"와 같은 질문에 답할 근거가 없었습니다.

이번에 소개할 OpenBot 프로젝트는 이러한 보안 담당자의 질문에 답할 수 있는 형태로 에이전트 실행 환경을 구성한 자체 호스팅(Self-hosted) 플랫폼입니다. OpenBot의 설계는 크게 2가지로 구성되어 있습니다: 하나는 봇마다 각각 격리된 컨테이너 기반의 Chromium과 작업 디렉토리를 할당하여 서로의 로그인과 파일을 볼 수 없게 하는 것이고, 다른 하나는 봇이 브라우저/파일/MCP 서버/컴포넌트에 손대는 모든 호출을 단 하나의 게이트웨이로 모아 정책을 평가하고 감사 행(audit row)을 남긴 뒤에야 실제 동작을 부르는 것입니다. 거부할 때는 어떤 규칙 때문에 거부했는지를 함께 남깁니다.

OpenBot은 CopilotKit이 공개했고, 에이전트와 사용자 인터페이스 사이의 개방형 프로토콜인 AG-UI (:pytorch::kr: AG-UI: 사용자와 에이전트의 상호작용을 위한 프로토콜 (feat. CopilotKit)) 위에 서 있습니다. AG-UI를 말하는 엔드포인트면 LangGraph, Mastra, CrewAI, Pydantic AI, Google ADK 중 무엇으로 만들었든, 혹은 직접 손으로 짰든 똑같이 등록됩니다. 현재 OpenBot 프로젝트는 아직 초기 상태이므로 이를 감안해 살펴보시기 바랍니다.

OpenBot의 게이트웨이가 도구 호출을 처리하는 순서

OpenBot에서 봇이 브라우저를 조작하거나 파일을 읽는 일은 봇이 직접 하는 것이 아닙니다. 호출은 서버의 게이트웨이로 돌아오고, 게이트웨이는 네 단계를 순서대로 밟습니다. 서버가 들고 있는 화면 스냅샷에서 대상을 확정하고, 현재 정책을 평가하고, 결정 내용을 감사 행으로 쓰고, 그제야 컴퓨터를 호출합니다. 전달된 동작이 실패하면 감사 행을 하나 더 씁니다. 기록이 먼저 존재하지 않는 실행 경로는 없다는 것이 이 구조의 핵심이며, 저장소는 컴퓨터가 노출하는 저수준 엔드포인트를 게이트웨이 우회에 쓰지 말라고 함께 안내합니다.

아래 그림은 사용자의 요청이 서버를 거쳐 봇에 전달되고, 봇의 도구 호출이 다시 게이트웨이로 돌아와 각자의 컴퓨터로 향하는 흐름을 보여줍니다:

정책은 CEL(Common Expression Language) 식으로 씁니다. 규칙이 들여다볼 수 있는 값은 도구 이름(tool.name), 의도(intent), 봇과 행위자 식별자(bot.id, actor.id), 페이지 주소와 호스트(page.url, page.host), 화면 요소(element.ref, element.role, element.name, element.type), 눌린 키(key), 파일 경로와 확장자(file.path, file.name, file.extension), MCP 관련 값(mcp.server, mcp.tool, mcp.effect)입니다. 평가는 실패 시 닫히는(fail-closed) 방향으로 설계되어 있어서, 정책이 비어 있으면 아무것도 허용하지 않고 규칙이 깨져 있으면 거부 쪽으로 기웁니다. 거부 규칙이 허용 규칙보다 먼저 평가되고, 형식이 잘못된 정책은 서버 자체가 뜨지 않습니다. 다만 배포판이 처음 들고 시작하는 기본값은 deny: [] 와 allow: ["true"] 이므로, 관리자가 /admin/boundaries 에서 정책을 세우거나 AGENT_COMPUTER_POLICY 를 넘기기 전까지는 게이트웨이가 기록만 하고 막지는 않습니다.

OpenBot이 봇마다 만들어 주는 전용 컴퓨터

COMPUTER_SUPERVISOR_URL 이 설정되면 감독자(supervisor) 서비스가 봇 하나마다 컨테이너 하나, /workspace 볼륨 하나, 브라우저 프로필 하나를 만듭니다. 이렇게 하면 어떤 봇도 다른 봇의 파일을 읽거나 다른 봇의 로그인을 재사용할 수 없습니다. 이 설정이 없으면 모든 봇이 하나의 AGENT_COMPUTER_URL 을 공유합니다. 호스트가 지원하면 COMPUTER_RUNTIME=runsc 로 gVisor 위에서 컨테이너를 띄울 수 있고, 컴퓨터는 기본적으로 127.0.0.1 에만 바인딩되며 컨테이너별 토큰을 요구합니다.

컴퓨터가 제공하는 것은 브라우저만이 아닙니다. 봇은 자기 작업 디렉토리에서 명령을 실행하고, 필요한 것을 설치하고, 저장한 파일을 다시 처리할 수 있습니다. 이 셸도 같은 게이트웨이를 지나므로 규칙 하나로 셸 자체를 막거나 특정 명령만 거부할 수 있고, 어느 쪽이든 실행 시도는 기록에 남습니다. 명령이 물려받는 환경 변수는 PATH, 로캘, 터미널, 프록시 관련 값으로 제한되며 배포 환경의 나머지 변수는 넘어가지 않습니다. 프록시 URL에 붙은 사용자 정보는 제거됩니다.

사람이 끼어드는 자리: 핸드오버와 비밀 입력

로그인 화면이나 2단계 인증(2FA, Two-Factor Authentication) 앞에서 봇이 멈추면 사람에게 도움을 요청합니다. 화면 옆 같은 패널에서 제어권을 넘겨받아 사람이 직접 조작하고 다시 돌려줄 수 있으며, 이 과정은 computer.help_requested, computer.control_taken, computer.control_released 세 가지 사건으로 기록됩니다. 사람이 브라우저를 잡고 있는 동안 봇의 동작은 대기열에 쌓이지 않고 거부됩니다.

비밀 값 입력은 대화 내용과 분리되어 있습니다. 감사 기록에는 비밀이 요청되고 제공됐다는 사실과 글자 수만 남고 값 자체는 남지 않습니다. 저장한 파일도 같은 원칙을 따라 경로와 크기만 기록하고 내용은 기록하지 않는데, 봇이 비밀로 전달받은 내용을 저장하고 있을 수 있기 때문이라고 저장소가 이유를 밝히고 있습니다.

OpenBot을 구성하는 서비스

scripts/start.sh 을 실행하였을 때 다음과 같은 서비스들이 실행됩니다:

서비스 포트 역할
app 3010 채널, 봇 대화, 실시간 화면, 관리 화면을 담당하는 React/Vite 인터페이스
server 3001 API와 CopilotKit 런타임(Runtime), 인증, 정책, 감사, 플러그인, 컴포넌트, 채널
agent-computer 4100 Chromium과 /workspace, 브라우저 프로필, 스크린샷, 파일 도구
agent-bot 4200 개념 검증용 AG-UI 봇
agent-langgraph 4201 LangGraph 기반 AG-UI 봇
supervisor 4500 (호스트) / 4300 (컨테이너) 봇별 컴퓨터 컨테이너의 생성, 중지, 초기화, 목록 조회
PostgreSQL + pgvector 5432 제품 데이터, 감사 행, 자격 증명, 정책, 권한, 채널, 컴포넌트
CopilotKit Intelligence 외부 재시작을 견디는 대화 스레드와 메모리

위 표에서 마지막 줄이 눈에 띕니다. OpenBot 자체는 MIT 라이선스의 오픈소스이지만, 대화 스레드와 메모리를 담당하는 CopilotKit Intelligence는 저장소 밖의 별도 서비스이고 프로젝트 키와 라이선스가 필요합니다. 무료 요금제가 있고 직접 호스팅하는 것도 가능하다고 안내되어 있지만, 완전히 자급자족하는 구성을 기대했다면 이 지점을 먼저 확인해야 합니다.

MCP 연동에서 OpenBot이 내린 선택

MCP 서버 연동은 관리자 권한으로만 설정할 수 있습니다. 저장된 자격 증명으로 외부 시스템에 닿을 수 있기 때문입니다. 반면 스킬(Skill)은 재사용 가능한 지시문일 뿐이라 개인이 만들어 자기 소유의 봇에만 붙일 수 있고, 배포 전체에 적용되는 스킬은 관리자가 만듭니다. 권한과 지시를 다른 등급으로 나눈 셈입니다.

카탈로그에 실제로 올라 있는 커넥터는 Google Drive 하나뿐입니다. Atlassian, Box, Slack, Salesforce, ServiceNow도 검토했지만 다시 뺐고, 프로젝트는 검증하지 않은 커넥터 다섯 개를 화면에 늘어놓는 것이 이 배포가 책임질 수 있는 범위를 넘어선다고 이유를 적어 두었습니다. Google Drive는 사용자 OAuth 방식이라 봇이 질문한 사람의 자격으로 읽으며, 그 사람이 볼 수 있는 문서만 봅니다. 직접 붙이는 MCP 서버는 URL 검사를 통과해야 하고, 읽기라고 확실히 분류되지 않은 도구는 모두 쓰기로 취급됩니다.

OpenBot이 맞는 팀과 아직 이른 팀

사내 에이전트를 도입하려는데 감사 추적과 권한 분리가 먼저 요구되는 상황이라면 지금 살펴볼 값어치가 있습니다. 이미 LangGraph나 CrewAI로 만들어 둔 에이전트가 있다면 AG-UI 엔드포인트로 노출하는 것만으로 그대로 얹을 수 있어 교체 비용이 크지 않고, 감사 화면과 정책 화면이 처음부터 관리자 화면으로 들어 있어 별도 구축이 필요 없습니다. 봇마다 격리된 브라우저가 필요한 업무(여러 계정으로 같은 SaaS에 로그인해야 하는 경우)도 잘 맞습니다.

반대로 지금 프로덕션에 올릴 대상은 아닙니다. 프로젝트가 스스로 알파라고 밝히고 있고, 저장소가 처음 만들어진 것이 2026년 8월 중순이라 배포 사례가 쌓일 시간이 없었습니다. 기본 정책이 전부 허용이므로 설치 직후 상태는 "기록은 남지만 막지는 않는" 구성이라는 점도 알고 있어야 합니다. 문서에는 channels.allowed_groups 처럼 선언은 되어 있으나 아직 동작하지 않는 항목들도 솔직히 적혀 있습니다. Docker와 Bun 1.3 이상이 필요하고, 셀프 호스팅이라도 CopilotKit Intelligence 키가 있어야 서버 실행이 가능하다는 점까지 합치면, 완전한 폐쇄망 배포를 전제로 한 팀에게는 OpenBot이 아직 적절한 선택지가 아닙니다.

사람과 에이전트가 같은 채널에서 일하는 형태 자체가 목적이라면 Buzz와 같은 자체 호스팅 워크스페이스가, 에이전트에게 컴퓨터 사용 능력만 붙이는 것이 목적이라면 open-computer-use 쪽이 더 가벼운 출발점입니다. OpenBot이 이들과 다른 점은 실행 환경과 정책 심사, 감사 기록을 포함하여 하나의 프로젝트로 구성하였다는 점입니다.

OpenBot 설치 및 사용법

Docker와 Bun 1.3 이상, 그리고 CopilotKit Intelligence 자격 증명과 모델 키가 준비물입니다. 먼저 환경 파일을 만들고 Intelligence 자격 증명을 받아 옵니다:

cp .env.example .env

npx --yes copilotkit@latest login
npx --yes copilotkit@latest project select
npx --yes copilotkit@latest license --write

project select 가 알려주는 cpk-... 런타임 키를 .env 의 INTELLIGENCE_API_KEY 에 넣고 OPENAI_API_KEY 를 채운 뒤 실행합니다:

bun install
bash scripts/start.sh

scripts/start.sh 는 Docker 서비스를 띄우고 마이그레이션을 적용한 다음 API 서버를 3001, 앱을 3010에서 시작하고, 각 서비스가 자기 상태 확인 경로에 응답하는지까지 검사합니다. 브라우저에서 http://localhost:3010 을 열면 됩니다.

배포용으로는 앱과 API, 봇이 사용할 브라우저를 한 이미지에 담아 올릴 수 있습니다. Kubernetes 없이 같은 .env 로 동작합니다:

docker build -t openbot .
docker run -p 3001:3001 --env-file .env \
  -e EMBEDDED_POSTGRES=on -v openbot-data:/var/lib/postgresql/data openbot

.env.example 에는 OPENBOT_SINGLE_USER=true 가 들어 있어 처음 내려받은 상태에서는 모든 요청을 하나의 관리자로 통과시킵니다. 다른 사람이 접근하기 전에 반드시 이 줄을 지우고 Google, Microsoft, Okta 중 하나를 설정해야 하며, 설정하지 않으면 서버는 모두를 관리자로 받아들이는 대신 기동을 거부합니다. 로컬이 아닌 곳에 올린다면 TLS를 앞에 두라는 안내도 함께 적혀 있습니다. 환경 변수 전체 목록은 저장소의 docs/configuration.md, 배포 시 최소 사양과 다중 복제본 동작은 docs/deployment.md에 정리되어 있습니다.

OpenBot의 라이선스

OpenBot은 MIT 라이선스로 공개되어 있어 개인 및 상업적 목적으로 자유롭게 사용할 수 있습니다.

단, 대화 스레드와 메모리를 담당하는 CopilotKit Intelligence는 이 라이선스가 적용되는 저장소 밖의 별도 서비스입니다. 서버가 기동하려면 이쪽 라이선스 토큰이 필요하므로, 도입 전에 요금제와 자체 호스팅 조건을 따로 확인해야 합니다.

:house: OpenBot 소개 페이지 (CopilotKit 공식 사이트)

:github: OpenBot 프로젝트 GitHub 저장소

더 읽어보기




이 글은 GPT 모델로 정리한 초안을 바탕으로 한 것으로, 원문의 내용 또는 의도와 다르게 정리된 내용이 있을 수 있습니다. 관심있는 내용이시라면 원문도 함께 참고해주세요! 읽으시면서 어색하거나 잘못된 내용을 발견하시면 댓글로 알려주시기를 부탁드립니다. :hugs:

이 도구를 직접 설치해 사용해보셨다면, :pytorch:파이토치 한국 사용자 모임:south_korea: 회원들을 위해 경험이나 팁을 댓글로 남겨주세요! :folded_hands: