"웹뷰는 부탁만 할 수 있어. 행동은 코어만 해."
누가 뭘 돌리나
뇌가 둘이라고 생각해봐. 웹뷰 뇌는 화면의 말로 생각해 — DOM, 이벤트, 레이아웃, 네 React 트리. 얘는 샌드박스 안에 있어서 서버처럼 파일을 열지도, 프로세스를 띄우지도, 네트워크를 읽지도 못해. 코어 뇌는 기계의 말로 생각해 — 파일, 소켓, OS API, 스레드. 얘한테는 못 하는 게 없어. Tauri 설계의 전부가 이 둘을 붙여놓되, 못 믿을 쪽(웹뷰 — 원격 콘텐츠나 공격자가 손댄 걸 그릴 수도 있잖아)이 힘 있는 쪽으로 곧장 손을 못 뻗게 막는 데 쓰여.
그래서 둘은 서로 함수를 직접 안 불러. 메시지를 보내지. 웹뷰가 invoke('do_thing', { ... })를 부르면 Tauri가 그걸 네가 #[tauri::command]로 표시해둔 Rust 함수로 넘기고, 그 함수는 코어에서 돌아서 값을 돌려주고, 웹뷰 쪽엔 resolve된 Promise로 도착해.
경계를 넘는 건 전부 데이터
두 반쪽이 메모리를 안 나눠 가지니까, 다리를 넘는 건 뭐든 직렬화를 거쳐 — 한쪽에서 평범한 데이터(JSON을 떠올리면 돼)로 풀렸다가 반대쪽에서 다시 조립돼. 살아 있는 파일 핸들이나 DB 커넥션이 박힌 Rust 구조체를 웹뷰한테 건넬 순 없어. 건네는 건 숫자, 문자열, 배열, 객체야. HTTP API랑 대화할 때 이미 몸에 익힌 규율이랑 똑같아 — 선로 위로는 데이터가 다니지 살아 있는 참조가 다니진 않으니까. 지금 익혀두면 bridge 트랙이 당연하게 읽힐 거야.
이게 동시에 보안 이야기인 이유
메시지 경계는 그냥 배관이 아냐 — 울타리야. 웹뷰는 네가 등록해둔 command만, 그것도 (security에서 보겠지만) capability가 허락한 것만 invoke할 수 있어. 프론트엔드에 버그가 있든 스크립트가 주입되든 디스크를 rm -rf 할 수는 없어. 프론트엔드한텐 악용할 디스크 접근 자체가 없거든 — 코어한테 부탁만 할 수 있고, 코어는 허락받은 요청에만 답하니까.