뜯어본 생각공개

BrowserSkill — 내 브라우저를 «빌려주는» 방법

텐센트가 공개한 도구입니다. AI가 제 컴퓨터의 브라우저를, 제가 이미 로그인해 둔 그대로 쓰게 해 줍니다. 설계는 좋았는데 소스를 읽다가 문 지키는 코드가 스스로 적어 둔 자백을 만났습니다.

BrowserSkill 은 텐센트가 2026년 6월에 공개한 도구이고, AI 비서가 «내 컴퓨터의 브라우저»를 대신 조작하게 해 줍니다. 중요한 건 «브라우저»가 아니라 «내» 쪽입니다 — 새 브라우저를 띄우는 게 아니라, 제가 이미 로그인해 둔 그 크롬을 그대로 씁니다.

그런데 그러면 바로 곤란해집니다. AI가 제 브라우저를 쓰는 동안 저는 뭘 하죠. 보던 탭이 갑자기 딴 데로 넘어가면 그건 도우미가 아니라 방해입니다. 이 도구가 실제로 푼 문제는 「웹을 조작한다」가 아니라 「같은 브라우저를 둘이 나눠 쓴다」 쪽입니다.

AI는 브라우저와 직접 말하지 않는다 — 가운데 셋을 거친다 AI 비서 셸을 부를 수 있으면 됨 bsk 명령 한 줄 평범한 터미널 명령 중계 프로그램 내 컴퓨터 안에서만 브라우저 확장 실제로 클릭하는 쪽 내 크롬 로그인된 그대로 그리고 그 크롬 안이 둘로 갈린다 — 이 칸막이가 이 물건의 알맹이다 에이전트 전용 창 AI는 여기서만 논다. 새로 열리고, 일이 끝나면 닫힌다 내가 보던 창 기본은 손도 못 댄다. 한 탭씩 «빌려야» 만질 수 있다
사슬이 긴 이유는 안전 때문이 아니라 호환 때문이다 — 가운데를 셸 명령으로 끊어 놨더니 AI 비서 종류를 안 가리게 됐다.

로그인이 필요한 일은 AI가 손을 못 대던 자리였습니다

AI에게 웹을 시키는 방법은 예전부터 있었습니다. 다만 대부분 아무도 로그인하지 않은 깨끗한 브라우저를 새로 띄웁니다. 그러면 공개된 페이지는 읽는데, 제 메일함이나 제 주문 내역처럼 로그인해야 보이는 것은 못 봅니다.

방법이 둘 있었습니다. 하나는 테스트용 계정을 따로 만들어 주는 것 — 그런데 제가 보려는 건 제 계정의 내용이니 소용이 없습니다. 다른 하나는 아이디와 비밀번호를 AI에게 주는 것 — 이건 하면 안 되는 쪽입니다.

BrowserSkill 의 답은 셋째입니다. 이미 로그인된 브라우저를 «그대로» 쓴다. 비밀번호를 건네지 않아도 되는 이유는, 애초에 로그인을 다시 할 필요가 없기 때문입니다.

그래서 새 브라우저를 만드는 대신 «새 창»을 만들었습니다

여기가 이 물건에서 제일 잘한 자리입니다. AI에게 브라우저를 통째로 넘기지 않고, 창을 하나 새로 띄워서 거기에 가둡니다. 로그인 정보는 브라우저 계정에 붙어 있으니 새 창에서도 그대로 살아 있고, 제가 보던 창은 손이 안 닿습니다.

보통은 여기는
AI가 쓰는 브라우저 아무도 로그인 안 한 새 것 내 것, 로그인된 그대로
내가 보던 화면 같이 쓰다 보니 뺏긴다 다른 창이라 안 뺏긴다
일이 끝나면 그냥 남는다 그 창이 닫힌다

교훈은 「가두면 나눠 쓸 수 있다」입니다. 같은 자원을 둘이 쓰려면 서로 안 보이게 칸을 치는 게 먼저지, 순서를 정하는 건 그다음입니다.

제 탭을 만지려면 «빌려야» 하고, 끝나면 돌려놓습니다

그래도 「내가 지금 보고 있는 이 페이지, 이거 좀 해 줘」가 필요할 때가 있습니다. 그때는 AI가 그 탭을 지목해서 빌립니다. 화면에 확인창이 뜨고, 제가 승낙해야 넘어갑니다.

빌려간 탭은 에이전트 전용 창으로 실제로 옮겨집니다. 그리고 일이 끝나면 돌아옵니다 — 이때 원래 어느 창의 몇 번째 자리에 있었는지를 미리 적어 뒀다가 그 자리로 되돌려 놓습니다.

이 마지막 한 줄이 제가 제일 오래 본 곳입니다. 빌리는 것까지는 다들 생각하는데, 돌려놓을 자리를 적어 두는 것은 잘 안 합니다. 안 적어 두면 반납이 「대충 아무 데나」가 되고, 그러면 결국 사람이 다시 찾습니다.

그런데 「빌려야 만진다」는 «쓰기»에만 해당합니다

여기서 값을 치렀습니다. 소개 문구는 「그 탭을 명시적으로 빌려야 한다」 고 못을 박습니다. 저는 그 문장을 「내 탭은 허락 전엔 아무것도 못 한다」로 읽었습니다.

소스를 열어 보니 아니었습니다. 도구가 성질별로 셋으로 갈려 있고, «가만히 읽기만 하는» 것들은 검사를 통째로 건너뜁니다. 그래서 페이지 구조를 떠 오는 것, 그 페이지의 오류 기록이나 통신 기록을 가져오는 것은 빌리지 않고도 됩니다.

제가 읽은 것 — 내 탭은 허락 없이는 아무것도 못 한다

실제 — 허락이 필요한 건 «바꾸는 일»이고, «읽는 일»은 그냥 된다

이건 버그가 아니라 문서에 안 적힌 설계입니다. 개발자용 문서에는 한 줄이 있고 코드 주석도 의도를 밝힙니다. 깨진 건 첫 화면의 홍보 문장이었습니다.

교훈: 한 문장으로 요약된 안전 규칙은, 그 문장이 «무엇에» 적용되는지를 같이 읽어야 합니다. 「빌려야 만진다」는 참인데, 「만진다」의 범위가 제 생각보다 좁았습니다.

문을 지키는 코드가 얼굴이 아니라 «옷차림»만 봅니다

구조 문서에는 「확장 허용 목록으로 연결을 검사한다」 고 적혀 있습니다. 「허용 목록」이라는 말은 당연히 «우리 확장만 통과»로 읽힙니다.

실제 코드는 이렇게 검사합니다 — «이름이 32글자이고, 전부 a부터 p 사이 글자인가». 그게 전부입니다. 브라우저 확장은 이름이 다 그렇게 생겼습니다. 즉 확장처럼 생긴 것이면 무엇이든 통과합니다.

놀란 건 그다음이었습니다. 바로 그 코드 위에 개발자가 스스로 적어 둔 주석이 있었습니다 — 요지는 «설정에서 받은 이름으로 좁혀야 하는데 지금은 안 하고 있다, 같은 컴퓨터에 깔린 다른 확장은 이 문을 그냥 지나간다»입니다. 하루 전에 바깥에서도 같은 지적이 올라와 있었고, 아직 열려 있습니다.

교훈: 「허용 목록」이라는 «말»과 실제 검사 «식»은 다른 물건입니다. 그리고 이 경우엔 코드 주석이 홍보 문구보다 정직했습니다 — 문서를 더 읽을 게 아니라 코드를 열었어야 빨랐습니다.

저는 안 깔기로 했습니다 — 이미 되고 있어서

좋은 물건인데 제 자리에는 안 들어갑니다. 이유는 성능이 아니라 자리 겹침입니다.

제가 쓰는 브라우저 자동화가 이미 둘 있고, 둘을 합치면 BrowserSkill 이 주는 것을 거의 다 덮습니다. 하나는 제 브라우저를 안 뺏고, 다른 하나는 제 로그인 상태를 씁니다. BrowserSkill 만 가진 칸은 「그 둘을 동시에」 한 칸뿐이었습니다.

그 한 칸의 가격표가 문제였습니다. 이 도구를 쓰려면 제 회사 일이 전부 로그인돼 있는 그 크롬에, 남이 만든 확장을 «모든 사이트 접근» 권한으로 심어야 합니다. 그리고 앞 절에서 본 문지기가 그 집의 현관입니다.

얻는 것 치르는 것
지금 칸 하나가 빈다 없음
깔면 그 칸이 찬다 로그인된 브라우저에 남의 확장 · 되돌려도 이미 지나간 것은 못 되돌린다

교훈: 「되돌리기 비용」을 칸으로 만들어 두면 이런 판단이 빨라집니다. 확장은 지우면 그만이지만, 그 사이 지나간 로그인 정보는 지울 수가 없습니다. 되돌릴 수 있는 것과 없는 것을 갈라 적는 순간 답이 나왔습니다.

그래서 다시 열 조건을 적어 뒀습니다

조건 없는 보류는 반년 뒤에 같은 조사를 처음부터 다시 하게 만듭니다. 그래서 셋을 적었습니다. 지금 쓰는 것들이 못 여는 사이트가 나올 때 · 제 크롬의 로그인이 꼭 필요한 일이 생길 때 · 저 문지기 문제가 닫힐 때. 셋 중 하나라도 켜지면 다시 봅니다.

안 깔면서도 가져온 것이 둘 있습니다

도구를 기각해도 설계는 가져올 수 있습니다. 오히려 여기가 이 편의 수확입니다.

첫째, 결과를 «됐다 / 안 됐다» 둘이 아니라 «모르겠다»를 넣은 셋으로 돌려주는 것. 이 도구는 브라우저 조작의 결과를 «아무 일도 안 일어남 / 확실히 됨 / 모름» 셋으로 돌려주고, «모름»일 때 다시 시도하는 것을 규칙으로 금지합니다. 파일을 올리는 일이라면, 「모르겠다」에서 한 번 더 누르면 두 번 올라갑니다.

저는 이 병을 이미 세 번 겪었습니다. 「보냈다」를 「됐다」로 읽는 것 말입니다. 매번 경고문을 적어 뒀는데, 정작 돌려주는 값 자체는 계속 두 가지였습니다. 경고문은 사람이 읽어야 작동하고, 값은 안 읽어도 작동합니다.

둘째, 「기본은 못 만진다 → 하나씩 빌린다 → 끝나면 돌려준다」. 저도 위험한 자동화에는 승인 절차를 걸어 뒀는데, 다시 보니 «돌려준다»가 없었습니다. 한 번 연 문이 계속 열려 있는 항목들이 있습니다.

그리고 남는 원리 하나

「할 수 있다 / 없다」 둘로 나눈 권한은, 실제로는 「지금 이것만, 끝나면 반납」이 필요했던 자리를 전부 «할 수 있다» 쪽으로 밀어 넣습니다.

브라우저는 그게 특히 나쁜 물건입니다. 전부 주면 제가 보던 창이 사라지고, 아무것도 안 주면 로그인 상태라는 알맹이를 못 씁니다. 그래서 «하나씩·시한부·반납»만 남는 답이었습니다.

못 한 것

  • 깔아서 돌려 보지 않았습니다. 이 편의 판정은 전부 소스와 이슈를 읽은 것이고, 잘 되는지 안 되는지는 한 번도 안 쟀습니다. 안 깐 이유가 「깔기 자체가 위험」이라, 확인할 길이 스스로 막혀 있습니다.
  • 저쪽이 넣어 둔 평가 세트를 안 돌렸습니다. 성공률을 실측할 유일한 길이었는데 안 썼습니다.
  • 원격으로 쓰는 모드는 읽기만 했습니다. 이 편의 보안 이야기는 내 컴퓨터 안에서 쓸 때에 한합니다.
  • 경쟁 도구를 나란히 놓고 대조하지 않았습니다. 같은 일을 하는 다른 자동화 도구 둘을 후보에 넣어 비교했다면 판정이 더 단단했을 텐데, 이번엔 안 했습니다.

여기부터는 자세한 기록입니다

이 저장소에서 가져올 것은 도구가 아니라 경계 설계다. BrowserSkill 은 텐센트가 2026-06-22 에 공개한 MIT 프로젝트로, 에이전트 하네스(Claude Code·Cursor·Codex 등)와 사용자의 로그인된 Chromium 을 잇는 로컬 다리다. 파는 것은 「이미 로그인된 브라우저를 쓰되 사용자의 작업은 안 끊는다」이고, 그걸 위해 Agent Window 격리 · 탭 빌림/반납 · 사람 호출 셋을 만들었다. 설계는 좋다. 그런데 소스를 읽으면 로컬 데몬의 확장 인증이 신원이 아니라 «모양»만 본다는 사실이 나오고, 그 사실을 코드 주석이 스스로 인정한다. 판정은 도구 도입 보류, 기법 수확 2종 채택이다.

무엇을 하는 물건인가

MCP 서버가 아니라 셸 CLI 다. 이게 이 프로젝트의 첫 설계 결정이고, 하네스 종속을 없앤 이유다. 「셸을 부를 수 있는 에이전트면 무엇이든」이 성립 조건이며, 하네스에는 사용법을 가르치는 SKILL.md 한 장(15.4KB)을 깐다.

구성은 넷이고, 에이전트는 브라우저와 직접 말하지 않는다.

무엇 통신
bsk CLI 동사-명사 하위명령 (bsk session start, bsk click) 셸에서 호출
bsk daemon 세션 라우팅 · 세션당 직렬 큐 · 유휴 종료 CLI ↔ 데몬은 로컬 IPC(UDS / 명명 파이프)
확장 (MV3) 도구 21종 디스패처 · 세션 관리 · ref 저장소 데몬 ↔ 확장은 127.0.0.1:52800 WebSocket
브라우저 Agent Window · 빌린 탭 확장 → 크롬은 CDP

규모는 Rust 47,773 줄 + TypeScript/TSX 98,924 줄(2026-09-18 실측, 테스트 포함). 별 4,439, 기여자 16명인데 상위 6명이 커밋의 거의 전부라 사내 팀이 만들어 공개한 것에 가깝다. 열린 이슈 31 · 닫힌 이슈 61. 릴리스는 0.2.0(09-02) → 0.2.1(09-09) → 0.3.0(09-16) 으로 2주 간격이다 — 활발하다는 뜻이면서 API 가 아직 안 굳었다는 뜻이다.

이 저장소는 성능 수치를 하나도 안 내건다. 벤치마크 자랑도, 「N% 성공」도 없다. 대신 evals/browser 에 결정론적 로컬 페이지와 에이전트 중립 평가 세트를 넣어 뒀다. 정직한 쪽이지만, 뒤집으면 얼마나 잘 되는지 저쪽도 숫자로는 모른다는 뜻이다.

대표 설계 결정 — 성립 조건까지 같이 적는다

조건 없이 옮긴 기법은 다른 환경에서 안 먹는다. 그래서 「어떤 제약이 이 설계를 강요했나」를 같이 본다.

결정 구현 성립 조건
Agent Window 격리 쓰기 도구는 대상 탭의 창 번호가 세션의 Agent Window 와 다르면 permission_denied 브라우저가 창 단위로 세션을 가를 수 있을 것. 탭 중심 UI 에서는 이 경계가 사람 눈에 안 보인다 — 실제로 그 요청이 이슈로 올라와 있다
빌림 / 반납 빌리면 탭이 Agent Window 로 물리적으로 이동하고, 원래 창 번호와 자리 번호를 기록해 뒀다가 반납 때 복원 돌려놓을 자리를 미리 적을 것. 안 적으면 반납이 사람 일이 된다
권한의 정본이 CLI 가 아니라 브라우저 설정 0.3.0 에서 무인 실행용 플래그 셋을 지우지 않고 «무력화» 했다 — 받기는 받되 확장 스위치를 못 이긴다 사람이 그 화면 앞에 있을 것. 무인 실행에서는 성립하지 않아, 그쪽은 「확장에서 스위치를 끄라」로 밀어냈다
사람 호출 캡차·로그인·OTP·결제에서 사람에게 넘기고 이어서 진행. 결과는 다섯 값 「거절」과 「기능 꺼짐」이 다른 값일 것. 문서가 «꺼짐 = 사람이 확인한 적 없음 = 권한이 는 것도 아님»을 못 박는다
결과 3값 브라우저 조작은 none / committed / unknown 을 돌려주고, 타임아웃·전송 끊김에도 unknown보존되며 맹목적 재시도를 금지 재시도 비용이 비대칭일 것. 멱등한 조회에는 과설계
참조표를 페이지마다 폐기 관측할 때마다 요소 참조(@e1 식)를 새로 만들고, 옛 참조 재사용을 규약으로 금지 관측과 조작 사이에 페이지가 변할 수 있을 것. 정적 페이지면 필요 없다

깨본 결과 — 소스와 이슈에서 확정된 것 넷

① 확장 허용 목록은 신원이 아니라 모양만 본다

문지기 함수는 chrome-extension:// 뒤가 32글자이고 전부 a–p 범위인지만 본다. MV3 확장 ID 는 전부 그 모양이므로 확장처럼 생긴 origin 은 무엇이든 통과한다. 그리고 바로 위 주석이 그 공백을 스스로 적어 뒀다 — 요지는 «설정·페어링에서 받은 ID 로 좁혀야 하는데 지금은 안 한다, 같은 머신의 사이드로드 확장이 이 문을 그냥 지나간다»이다. 2026-09-17 에 외부에서도 동일 지적이 이슈로 올라왔고 아직 열려 있다.

기본 포트는 loopback 에 묶여 있어 원격 공격은 아니다. 하지만 같은 PC 에 확장이 하나 더 깔리면 그 확장이 브라우저를 조작할 수 있다는 뜻이고, 그 브라우저에는 사용자의 모든 로그인이 들어 있다.

② 빌림은 쓰기에만 걸린다

도구가 효과별로 셋으로 분류돼 있고(수동 읽기 / 일시적 입력 / 브라우저 변경), 정책은 «수동 읽기이고 로컬이면 검사 없이 통과» 한 줄이다. 그래서 정적 접근성 트리를 뜨는 도구, 콘솔·네트워크 기록을 가져오는 도구는 빌리지 않고 사용자 탭에 닿는다(두 파일 전수 확인 — 창 검사 호출 0건).

⚠ 공정하게 적자면 이건 문서에 안 적힌 설계지 버그가 아니다. 개발자 문서에 「수동 읽기는 사용자 탭을 볼 수 있다」가 한 줄 있다. 깨지는 것은 첫 화면의 홍보 문장이다. 그리고 관측 도구는 passive_read아니라 「일시적 입력」으로 분류돼 Agent Window 안으로 강제된다 — hover 프로브가 실제 페이지를 건드리기 때문이다. 이 갈래는 제대로 나눠 놨다.

③ 윈도우가 가장 약한 자리다

열린 이슈 31건을 훑으면 윈도우 관련이 눈에 띄게 뭉쳐 있다 — 자동 기동한 데몬이 부모 프로세스와 함께 죽는 것, 확장 미연결 시 진단 명령이 무한 대기하는 것, 서명 없는 실행 파일이 OS 보안 기능에 차단되는 것, 세션 정지가 멈춘 명령을 못 죽이는 것. 0.2.1 의 수정 여섯 줄 중 넷이 윈도우다. 고치고 있다는 뜻이면서 어디가 아픈지가 그대로 드러난다.

④ 배경 창에서 클릭이 조용히 성공으로 보고된다

Agent Window 를 뒤에 두는 옵션으로 돌리면 클릭이 입력을 전달하지 않고도 성공을 보고한다는 이슈가 열려 있다(2026-09-14).

⚠ 아이러니는 같은 저장소가 결과 3값을 «모름이면 재시도 금지»까지 문서화해 놓고, 정작 그 클릭 하나에서 「모름」을 「성공」으로 낸다는 것이다. ⇒ 규약을 문서에 적는 것과, 모든 반환 지점이 그 규약을 지키는 것은 다른 일이다.

겹치는 칸과 안 겹치는 칸 — 새로 얻는 것은 아래 가운뎃줄 하나뿐이다 지금 쓰는 것 ① 내 브라우저를 안 뺏는다 ○ 내 로그인을 그대로 쓴다 ✕ 따로 로그인해 둔다 이미 쓰는 중 지금 쓰는 것 ② 내 브라우저를 안 뺏는다 ✕ 내 로그인을 그대로 쓴다 ○ 보던 탭을 같이 쓴다 이미 쓰는 중 BrowserSkill 내 브라우저를 안 뺏는다 ○ 내 로그인을 그대로 쓴다 ○ ← 여기 한 칸이 새것 대가: 남의 확장 심기 판정 — 도구 도입 보류. 새 칸은 하나인데 되돌리기 비용이 비대칭이다 다시 열 조건 셋: 지금 것이 못 여는 사이트 · 내 크롬 로그인이 꼭 필요한 일 · 문지기 이슈가 닫힐 때
판정을 바꾼 칸은 「이득」이 아니라 「되돌리기 비용」이었다. 확장은 지울 수 있지만 그 사이 지나간 세션은 못 되돌린다.

내 환경에 대봤다 — 새로 얻는 칸은 하나였다

현재 브라우저 자동화 스택은 둘이고, 둘을 합치면 이 도구가 주는 것을 거의 덮는다. 하나는 별도 앱이라 내 브라우저를 안 뺏지만 자체 프로파일이라 로그인을 따로 해야 하고, 다른 하나는 내 실제 크롬을 쓰지만 내가 보던 탭을 같이 쓴다.

BrowserSkill 만 가진 칸은 「그 둘을 동시에」 한 칸이다. 그리고 그 한 칸의 가격은 모든 사이트 접근 권한과 개발자 프로토콜 권한을 가진 남의 확장을, 업무 로그인이 전부 들어 있는 프로파일에 심는 것이다. 여기에 위 ①번 문지기가 겹친다.

대상 판정 이득 도입 비용 되돌리기 비용 신뢰도
도구 자체 보류 새 칸 1 셋 설치 · 윈도우 이슈 밀집 비대칭 — 확장은 지워도 노출된 세션은 못 되돌린다 높음 (소스·이슈 실측)
결과 3값 채택 큼 — 같은 오판을 이미 세 번 반환 타입 한 칸 + 호출부 분기 높음
빌림·반납 규약 채택 중 — 내 규약에 「반납」이 비어 있다 문서 한 절
옛 플래그 무력화 보류 낮음 낮음(미확인) — 그런 플래그가 있는지 안 셌다

채택 판정도 깨 봐야 한다. 「결과 3값」에 대해서는 이미 해결되고 있지 않나가 정당한 반문이다. 내 규칙 문서에는 «보냈다 ≠ 됐다»가 경고문으로 이미 적혀 있다. 그런데 러너가 돌려주는 값 자체가 3값인지는 안 열어 봤다(미확인). ⇒ 그래서 「채택」의 첫 작업은 구현이 아니라 현행 확인이다. 경고문은 사람이 읽어야 작동하고, 값은 안 읽어도 작동한다.

남는 원리

경계는 「누가 무엇을 할 수 있나」가 아니라 「무엇이 언제까지 빌려져 있나」로 그어야 한다.

「할 수 있다/없다」 2값으로 나눈 권한은, 실제로는 「지금 이 하나만, 끝나면 반납」이 필요했던 자리를 전부 «할 수 있다» 쪽으로 밀어 넣는다. 브라우저는 그게 특히 나쁜 자원이다 — 전부 주면 사용자의 화면이 사라지고, 전무를 주면 로그인 상태라는 알맹이를 못 쓴다. 그래서 «하나씩 · 시한부 · 반납»만이 남는 답이었고, 이 저장소는 세션 정지를 의무로 두고 유휴 정리를 «안전망일 뿐»이라고 못 박는 데까지 갔다.

내 쪽에 걸리는 자리는 한 번 연 문이 계속 열려 있는 항목들이다. 승인 절차는 있는데 반납 시점이 안 적혀 있다.

못 한 것

  • 설치해 돌려 보지 않았다. 판정은 전부 소스 읽기와 이슈 실측이고, 성공률·속도는 한 번도 안 쟀다. 「특정 사이트가 이 도구로 열리나」도 미확인이다 — 보류 사유가 「설치 자체가 위험」이라 확인 경로가 스스로 막혀 있다.
  • evals/browser 를 안 돌렸다. 실측 성공률을 얻을 유일한 길이었다.
  • 원격 모드는 읽기만 했다. 페어링·기기 자격증명 쪽은 코드로 확인하지 않았고, 이 편의 보안 판정은 로컬 모드에 한한다.
  • 대안 대조를 안 돌렸다. 같은 문제를 푸는 다른 자동화 후보 둘을 나란히 놓지 않았다. 셋 다 쓸 수 있는 상태라 나중에 값이 날 자리다.