SSD Nodes Learn Hosting plans →
Hướng dẫn Matt ConnorBởi Matt Connor · Cập nhật ngày 2026-08-22

Cho coding agent chạy trong VM dùng một lần

Chạy coding agent trong VM có thể xóa bỏ để giới hạn blast radius, giữ trạng thái sạch cho từng task và dùng snapshot, VPS để giảm chi phí.

Vì sao VM dùng một lần tốt hơn laptop của bạn

Cấp cho coding agent một VM dùng một lần. Trường hợp xấu nhất là agent phá hỏng một máy mà bạn có thể dựng lại trong mười phút. Agent vẫn có root, vẫn cài được package, vẫn chạy test suite mà không phải xin phép cho từng bước. Khác biệt nằm ở nơi thiệt hại xảy ra. Trên laptop, agent dùng chung home directory với SSH key, profile của browser, các file .env và mọi repository bạn từng clone. Trên một server dùng xong rồi bỏ, agent chỉ có shell, một checkout và không có gì khác đáng để lấy.

Đó là toàn bộ lập luận. Đây là lập luận về sự bất đối xứng, không phải về xác suất. Một agent cẩn thận trên một laptop được quản lý cẩn thận gần như lúc nào cũng ổn. Nhưng một lần xảy ra sự cố, chi phí không chỉ là một commit bị lỗi. Bạn phải restore từ backup, nếu bạn có backup.

Xác định phạm vi ảnh hưởng trước khi tranh luận

Phạm vi ảnh hưởng là tập hợp những thứ mà một process có thể truy cập. Với agent chạy dưới user thông thường trên máy tính bạn vẫn dùng hằng ngày, tập hợp này lớn hơn nhiều so với hình dung của hầu hết mọi người.

Phạm vi đó bao gồm ~/.ssh/id_ed25519, thường không được mã hóa vì bạn đã chán phải nhập passphrase. Nó bao gồm ~/.aws/credentials~/.config/gh/hosts.yml, vốn được thiết kế ở dạng plain text. Nó bao gồm mọi repository cùng cấp bên dưới ~/code, kể cả những repository có connection string của production trong file env cục bộ. Nó cũng bao gồm shell history, nơi lưu các token bạn từng dán vào một lần. Ngoài ra còn có network mà laptop của bạn đang kết nối, thường là mạng gia đình hoặc mạng văn phòng có các service không yêu cầu xác thực.

Không điều nào trong số đó cần một agent độc hại. Chỉ cần một command sai nhưng được thực thi một cách chắc chắn. rm -rf với một biến chưa được set và được expand thành /, một git clean -xfd chạy trong sai directory, một docker system prune -af --volumes kéo theo cả database cục bộ, hoặc một chmod -R 777 hữu ích trên home directory. Agent được train trên chính Internet đã dạy những command đó cho mọi người khác.

Cơ chế bảo vệ bạn không phải là khả năng phán đoán của agent. Đó là việc máy đang chứa thiệt hại là máy bạn đã chấp nhận có thể mất.

Chi phí rất đơn giản, và đó chính là điểm cần thấy

Một VPS nhỏ chỉ tốn vài dollar mỗi tháng. Khôi phục laptop của developer mất một ngày, và đó là trường hợp thuận lợi: bạn phát hiện sự cố ngay lập tức và đã có backup.

Hãy tự tính bằng các con số của bạn. Lấy mức phí theo giờ, nhân với số giờ cần để cài lại operating system, khôi phục home directory, rotate SSH key, rotate personal access token và re-clone 20 repository. So sánh kết quả đó với chi phí 12 tháng của server nhỏ nhất mà provider cung cấp. Điểm hòa vốn nằm ở mức chưa đến 1 sự cố trong vài năm, và sự cố không cần nghiêm trọng mới vượt qua mức này. Chỉ một buổi chiều bị mất vì local environment bị hỏng cũng đã đủ trả chi phí cho cả năm.

Nửa còn lại của phép tính là snapshot. Tạo snapshot trước khi chạy một tác vụ rủi ro sẽ biến một kết quả xấu từ “khôi phục toàn bộ môi trường làm việc” thành “rollback rồi thử prompt khác”. Laptop bạn đang dùng để viết nội dung này không có tùy chọn đó, vì bạn không thể tạo snapshot cho một máy đang được dùng làm máy làm việc.

Bức tranh tính đến tháng 7 năm 2026

Có 3 câu trả lời hợp lý cho câu hỏi “agent nên chạy ở đâu”, và chúng cùng đánh đổi giữa 2 yếu tố: ranh giới cô lập mạnh đến đâu và bạn chấp nhận phải thiết lập nhiều đến mức nào.

Một micro VM cục bộ. Các công cụ trong nhóm này khởi động một máy ảo thực trên phần cứng của bạn, mount repository vào đó và cho agent quyền root bên trong. clawk là ví dụ hiện tại. Thông điệp của công cụ này đúng với luận điểm của bài viết: cung cấp cho coding agent một Linux VM dùng tạm, không phải laptop của bạn. Tính đến tháng 7 năm 2026, công cụ này nhắm đến macOS 14 trở lên trên Apple silicon, có hỗ trợ Linux thử nghiệm thông qua Firecracker và cài đặt bằng brew install clawkwork/tap/clawk. Bạn chạy clawk bên trong một repository để khởi động sandbox và gắn agent vào đó, dùng clawk down để dừng sandbox và clawk destroy để xóa sandbox. Ranh giới ở đây là hypervisor nên khá mạnh. Hạn chế là VM vẫn chạy trên máy bạn thường mang theo, nên nó cạnh tranh tài nguyên memory và sẽ dừng khi bạn đóng nắp máy.

Một container. Docker là lựa chọn mà hầu hết mọi người đã cài sẵn, và nó thực sự hữu ích.

docker run --rm -it -v "$PWD:/work" -w /work --network none ubuntu:24.04 bash

--rm xóa container khi thoát, còn --network none tắt hoàn toàn network của container. Đây là thiết lập mặc định tốt cho một lần build hoặc test. Cần hiểu rõ những gì cách này không làm được: container dùng chung kernel với host, nên lỗi kernel có thể tạo đường thoát, và ranh giới cô lập biến mất ngay khi bạn thêm --privileged hoặc mount /var/run/docker.sock để agent có thể “dùng Docker”. Mount Docker socket vào container tương đương với việc cấp cho container quyền root trên host.

Một VPS thông thường có thể rebuild. Bạn không cần công cụ mới, có ranh giới kernel thực, có snapshot từ provider và VPS vẫn tiếp tục chạy khi bạn tắt laptop. Đây là mô hình được mô tả trong phần còn lại của hướng dẫn này. Đây cũng là mô hình phù hợp với các agent chạy lâu, vì một job mất 4 giờ không quan tâm bạn đã về nhà.

Mô hình VPS: cấp cho agent một user riêng

Bắt đầu với một server đã được harden. 10 phút đầu tiên trên một VPS mới bao gồm những phần không dành riêng cho agent: cập nhật hệ thống, đăng nhập bằng user không phải root, SSH chỉ dùng key và firewall.

Sau đó tạo một account chỉ dành cho agent. Nếu có lỗi bên trong account này, lỗi đó sẽ không thể tác động đến phần khác trên server.

sudo adduser --disabled-password --gecos "" agent
sudo install -d -m 700 -o agent -g agent /home/agent/work
sudo -u agent -H bash -lc 'id; ls -la ~'

--disabled-password nghĩa là không có password để đoán, và bạn truy cập account bằng sudo -u agent hoặc SSH key. Lưu ý rằng agent cố ý không thuộc group sudo. Agent có sudo sẽ có quyền root. root có thể đọc file của mọi user khác, nên lớp phân tách vừa tạo chỉ còn mang tính hình thức. Nếu agent thực sự cần cài package, đó là lý do để dùng hẳn một server do agent sở hữu, không phải cấp sudo cho agent trên một server dùng chung. Các nguyên tắc chung được nêu trong nguyên tắc quyền tối thiểu cho user Linux trên VPS.

Kiểm tra ranh giới này trước khi tin tưởng agent. Với tư cách user agent, thử đọc một file thuộc account của chính bạn:

sudo -u agent cat /home/you/.ssh/id_ed25519

Bạn sẽ thấy cat: /home/you/.ssh/id_ed25519: Permission denied. Nếu thay vào đó bạn thấy key material, home directory của bạn đang có mode 755 và cơ chế isolation chưa thực sự hoạt động. Sửa bằng sudo chmod 700 /home/you.

Để credential hoàn toàn bên ngoài máy

Mục đích của một máy dùng tạm sẽ mất đi nếu bạn sao chép secret production lên đó. Quy tắc rất đơn giản: trên máy đó không được có credential nào mà bạn không muốn rotate ngay trong chiều nay.

Với git, hãy forward SSH agent thay vì sao chép key. Private key vẫn nằm trên laptop của bạn, chỉ các yêu cầu ký mới đi qua kết nối.

ssh -A agent@203.0.113.10
ssh -T git@github.com

Lệnh thứ hai phải trả lời Hi yourname! You've successfully authenticated, but GitHub does not provide shell access.. Điều đó chứng minh git push sẽ hoạt động dù server không có file key. Sau đó chạy ls -la ~/.ssh trên máy đó và xác nhận không có private key nào trong đó.

Agent forwarding có một điểm cần lưu ý, hãy nói rõ: trong khi bạn đang kết nối, bất kỳ ai có root trên server đó đều có thể dùng socket được forward để authenticate với tư cách của bạn. Trên server mà người dùng duy nhất khác là bạn, đây là đánh đổi có thể chấp nhận. Trên máy dùng chung thì không, và deploy key chỉ có phạm vi trong một repository là lựa chọn tốt hơn. Các lựa chọn được trình bày trong Kiến thức cơ bản về quản lý SSH key.

Với API key, hãy cấp cho agent một key riêng với spending limit riêng, lưu trong file do user agent sở hữu với mode 600. Khi máy bị hủy, hãy revoke key đó thay vì phải đoán xem nó đã bị lộ hay chưa. Theo dõi model spend riêng cho từng key cũng là cách giữ cho các con số trong Kiểm soát chi phí AI agent trên VPS luôn có thể dự đoán.

Giới hạn các đích agent có thể truy cập trên network

Cô lập filesystem mới chỉ là một nửa của ranh giới bảo vệ. Nửa còn lại là egress: các đích mà process được phép kết nối. Linux có thể lọc traffic outbound theo user đã tạo process, đúng với mô hình này.

sudo iptables -A OUTPUT -m owner --uid-owner agent -o lo -j ACCEPT
sudo iptables -A OUTPUT -m owner --uid-owner agent -p udp --dport 53 -j ACCEPT
sudo iptables -A OUTPUT -m owner --uid-owner agent -p tcp --dport 443 -j ACCEPT
sudo iptables -A OUTPUT -m owner --uid-owner agent -j REJECT

Các rule được đọc theo thứ tự, vì vậy dòng REJECT cuối cùng sẽ bắt mọi kết nối mà các dòng trước chưa cho phép. Hãy kiểm tra bằng user của agent:

sudo -u agent curl -sS -m 5 http://example.com

Lệnh này phải fail với curl: (7) Failed to connect to example.com port 80: Connection refused, vì rule reject trả lời ngay thay vì để connection bị treo. Request HTTPS đến cùng host đó vẫn phải thành công.

Có 2 giới hạn cần nói rõ. Thứ nhất, các rule này sẽ mất sau lần reboot tiếp theo nếu bạn không lưu chúng bằng sudo apt install -y iptables-persistent rồi sudo netfilter-persistent save. Thứ hai, cơ chế này lọc port và địa chỉ, không lọc tên. Rule cho phép port 443 sẽ cho phép truy cập mọi HTTPS host trên internet. Như vậy đủ để truy cập model API, nhưng cũng đủ để truy cập một pastebin. Muốn có allow-list theo domain thực sự, traffic phải đi qua proxy có thể đọc hostname trong request. Cách này phức tạp hơn mức mà phần lớn setup của một developer thường muốn. Chỉ nên tuyên bố đúng phạm vi bạn đã triển khai: kiểm soát egress ở cấp port trên một máy mà bạn đã chuẩn bị tinh thần để mất.

Khôi phục trạng thái sạch giữa các tác vụ

Trạng thái sạch cho từng tác vụ là một lợi ích thường bị đánh giá thấp. Một agent đã xử lý ticket trước đó trong 3 giờ có thể để lại các package đã cài, migration mới áp dụng dở dang, một node_modules cũ và một git working tree chứa các thay đổi chưa được ai review. Tác vụ tiếp theo kế thừa toàn bộ số đó, còn bạn phải dùng thời gian review để xác định phần nào thuộc về lần chạy nào. Agent có phạm vi hẹp hơn sẽ để lại ít thứ hơn ngay từ đầu. Kết hợp một máy có thể hủy với skill hướng agent đến thay đổi nhỏ nhất nhưng vẫn hoạt động sẽ giữ cả diff và trạng thái còn sót lại ở mức đủ nhỏ để review.

Cách đơn giản và ít tốn kém là tạo checkout mới cho mỗi tác vụ.

sudo -u agent -H bash -lc 'rm -rf ~/work/repo && git clone git@github.com:you/repo.git ~/work/repo'

Cách chắc chắn hơn là tạo snapshot của provider một lần, ngay sau khi thiết lập máy và trước khi agent chạm vào máy. Khôi phục snapshot đó sẽ đưa toàn bộ system, bao gồm cả các package, về trạng thái đã biết. Hầu hết provider cung cấp tính năng này trong control panel hoặc qua API, thay vì dưới dạng command chạy trên máy, nên các bước cụ thể phụ thuộc vào provider của bạn. Hãy tạo snapshot khi máy vẫn chưa có thay đổi đáng kể.

Lưu mọi thứ bạn cần giữ bên ngoài máy có thể hủy. Điều này chủ yếu có nghĩa là push branch thay vì giữ chúng cục bộ. Nếu máy vẫn chứa thứ bạn sẽ tiếc nếu mất, hãy backup đúng cách bằng restic backup trên VPS. Một máy có thể hủy chỉ hữu ích nếu việc hủy nó thực sự không gây vấn đề.

Nếu muốn có nhiều môi trường cô lập mà không phải trả tiền cho nhiều server, bạn có thể dùng một VPS lớn hơn để chạy trực tiếp các guest VM. Virtualisation lồng nhau trên VPS giải thích cách hoạt động, bao gồm cách kiểm tra provider có cho phép hay không. Isolation có tác động theo cả hai hướng. Nếu muốn 2 agent trên cùng một máy phối hợp với nhau thay vì bị cô lập hoàn toàn, một session Claude Code có thể gửi text trực tiếp cho session khác thay vì để mọi lần bàn giao đều phải đi qua bạn.

Khi một laptop được bảo vệ cẩn thận thực sự là đủ

Hãy nói thẳng về điều này, vì phóng đại lợi ích của isolation sẽ khiến mọi người không còn lắng nghe.

Nếu bạn kiểm tra từng command trước khi chạy, laptop là đủ. Permission prompt là một cơ chế kiểm soát thực sự, và chạy Claude Code an toàn trên server giải thích từng cấp độ của cơ chế này thực sự chặn những gì. Nếu công việc của bạn chỉ nằm trong một repository và trên máy không có credential production nào, blast radius vốn đã nhỏ. Nếu các phiên làm việc với agent ngắn và được giám sát, thời gian phơi nhiễm cũng ngắn.

Câu trả lời thay đổi ngay khi bạn bỏ qua các prompt. Điều này đáng được cân nhắc từ bây giờ, vì auto mode trở thành mặc định của Claude Code vào ngày 14 August 2026 và bản cài mới không còn hỏi trước khi chỉnh sửa file hoặc chạy command. Các lần chạy không có người giám sát, job chạy qua đêm và mọi workflow trong đó bạn approve một plan rồi rời đi đều loại bỏ bước kiểm tra của con người, vốn đang thực hiện việc containment. Khi đó, máy phải tự thực hiện việc này. Điều tương tự cũng áp dụng cho mọi thứ mở rộng phạm vi truy cập của agent, bao gồm chạy coding agent trên VPS qua nhiều repository cùng lúc.

Quyết định này thực ra không phụ thuộc vào mức độ bạn tin model. Nó phụ thuộc vào những gì đang ở cạnh model khi model mắc lỗi.

FAQ

Container có đủ khả năng cô lập cho coding agent không?

Trong hầu hết trường hợp là đủ, với 2 điều kiện. Container không được chạy với --privileged và không được mount /var/run/docker.sock vào container, vì một trong hai điều này đều tạo đường dẫn để process có thể lấy root trên host. Container dùng chung kernel với host, nên ranh giới cô lập yếu hơn virtual machine. Nếu agent chạy code không đáng tin cậy được tải từ Internet, hãy ưu tiên một VM thực hoặc một server riêng.

Agent có cần sudo trên server không?

Không. Cấp sudo cho agent sẽ phá bỏ cơ chế cô lập đã thiết lập, vì root có thể đọc dữ liệu của mọi account khác trên máy. Tạo user cho agent mà không cấp sudo, rồi chỉ cho user này quyền ghi vào work directory của chính nó. Nếu task thực sự cần cài package, hãy cấp cho agent cả một machine do nó sở hữu thay vì cấp root trên một machine dùng chung.

Làm thế nào để cho agent push lên git mà không đặt SSH key của tôi trên máy?

Forward SSH agent bằng ssh -A khi kết nối. Các yêu cầu ký được truyền qua connection, còn private key vẫn nằm trên laptop của bạn. Vì vậy, ssh -T git@github.com có thể xác thực và git push hoạt động mà không cần private key trên server. Lưu ý rằng root trên server đó có thể sử dụng socket được forward trong lúc bạn đang kết nối. Do đó, trên mọi machine dùng chung với người khác, hãy dùng deploy key chỉ có phạm vi của repository.

Agent cần VPS có cấu hình bao nhiêu?

Công việc của agent chủ yếu là chỉnh sửa file, chạy build và chạy test, nên hãy chọn cấu hình machine theo yêu cầu của build thay vì theo model. Hosted model chạy trên hardware của provider, nên chỉ tạo thêm network traffic và gần như không tạo tải cục bộ. Hãy bắt đầu với 2 GB RAM cho các task scripting, rồi nâng lên 8 GB nếu repository build container hoặc compile thành phần lớn.

Bao lâu nên hủy và rebuild machine một lần?

Hãy rebuild khi không còn giải thích được trạng thái của machine, và tối thiểu là mỗi khi có khả năng credential trên machine đã bị lộ. Tạo checkout mới giữa các task sẽ xử lý tình trạng drift hằng ngày. Snapshot được tạo trước lần agent chạy đầu tiên sẽ cho bạn system image sạch để khôi phục khi cần. Nếu việc rebuild có vẻ tốn kém, đó là dấu hiệu một thành phần quan trọng đang nằm trên machine mà bạn gọi là disposable.