Claude Code và Agent SDK là những công cụ mạnh mẽ có thể thực thi code, truy cập file, và tương tác với dịch vụ bên ngoài thay mặt bạn. Giống như mọi công cụ có năng lực này, triển khai chúng một cách cẩn trọng giúp bạn hưởng lợi ích trong khi vẫn giữ được kiểm soát phù hợp.
Khác với phần mềm truyền thống đi theo các code path được định trước, các công cụ này tạo ra hành động của chúng một cách động dựa trên context và mục tiêu. Sự linh hoạt này là điều làm chúng hữu ích, nhưng cũng có nghĩa là hành vi của chúng có thể bị ảnh hưởng bởi nội dung chúng xử lý: file, trang web, hay input người dùng. Điều này đôi khi được gọi là prompt injection. Ví dụ, nếu README của một repository chứa hướng dẫn bất thường, Claude Code có thể đưa những hướng dẫn đó vào hành động của nó theo cách mà người vận hành không lường trước. Hướng dẫn này bao quát các cách thực tế để giảm rủi ro này.
Tin tốt là bảo mật một triển khai agent không cần hạ tầng kỳ lạ. Cùng các nguyên tắc áp dụng cho việc chạy bất kỳ code bán tin cậy (semi-trusted) nào cũng áp dụng ở đây: isolation, least privilege, và defense in depth. Claude Code có sẵn vài tính năng bảo mật giúp giải quyết các mối lo phổ biến, và hướng dẫn này đi qua các tính năng đó cùng các tùy chọn hardening bổ sung cho ai cần chúng.
Không phải mọi triển khai đều cần bảo mật tối đa. Một developer chạy Claude Code trên laptop có yêu cầu khác với một công ty xử lý dữ liệu khách hàng trong môi trường multi-tenant. Hướng dẫn này trình bày các tùy chọn từ tính năng bảo mật có sẵn của Claude Code đến kiến trúc production được hardened, để bạn chọn cái phù hợp với tình huống của mình.
Mô hình mối đe dọa (threat model)
Phần tiêu đề “Mô hình mối đe dọa (threat model)”Agent có thể thực hiện hành động ngoài ý muốn do prompt injection (hướng dẫn được nhúng trong nội dung chúng xử lý) hoặc lỗi model. Các model Claude được thiết kế để kháng cự điều này; xem tổng quan model và system card của model bạn triển khai để biết chi tiết đánh giá.
Dù vậy, defense in depth vẫn là thực hành tốt. Ví dụ, nếu một agent xử lý một file độc hại chỉ dẫn nó gửi dữ liệu khách hàng tới một server bên ngoài, network control có thể chặn hoàn toàn request đó.
Tính năng bảo mật có sẵn
Phần tiêu đề “Tính năng bảo mật có sẵn”Claude Code có sẵn vài tính năng bảo mật giải quyết các mối lo phổ biến. Xem tài liệu bảo mật để biết đầy đủ chi tiết.
- Hệ thống permission: Mỗi tool và bash command đều có thể được cấu hình để allow, block, hoặc hỏi người dùng phê duyệt. Dùng glob pattern để tạo rule như “cho phép mọi lệnh npm” hay “chặn mọi lệnh có sudo”. Tổ chức có thể set policy áp dụng cho toàn bộ user. Xem permissions.
- Parse command cho permission: Trước khi thực thi bash command, Claude Code parse nó thành một AST và so khớp kết quả với permission rule của bạn. Command không parse sạch được, hoặc không khớp allow rule nào, sẽ cần phê duyệt tường minh. Một số cấu trúc nhỏ như
evalluôn cần phê duyệt bất kể allow rule. Đây là một permission gate, không phải sandbox; nó không suy luận một command có nguy hiểm hay không từ target path hay hiệu ứng của nó. - Tóm tắt kết quả web search: Kết quả tìm kiếm được tóm tắt thay vì đưa raw content trực tiếp vào context, giảm rủi ro prompt injection từ nội dung web độc hại.
- Sandbox mode: Bash command có thể chạy trong một môi trường sandbox giới hạn truy cập filesystem và network. Xem tài liệu sandboxing để biết chi tiết.
Nguyên tắc bảo mật
Phần tiêu đề “Nguyên tắc bảo mật”Với các triển khai cần hardening bổ sung ngoài mặc định của Claude Code, các nguyên tắc sau định hướng các tùy chọn khả dụng.
Ranh giới bảo mật (security boundary)
Phần tiêu đề “Ranh giới bảo mật (security boundary)”Một security boundary ngăn cách các thành phần có mức độ tin cậy khác nhau. Với triển khai bảo mật cao, bạn có thể đặt tài nguyên nhạy cảm (như credential) bên ngoài ranh giới chứa agent. Nếu có gì sai sót trong môi trường agent, các tài nguyên bên ngoài ranh giới đó vẫn được bảo vệ.
Ví dụ, thay vì cho agent truy cập trực tiếp một API key, bạn có thể chạy một proxy bên ngoài môi trường agent để inject key vào request. Agent có thể gọi API, nhưng không bao giờ thấy credential thật. Pattern này hữu ích cho triển khai multi-tenant hoặc khi xử lý nội dung không tin cậy.
Least privilege
Phần tiêu đề “Least privilege”Khi cần, bạn có thể giới hạn agent chỉ có năng lực cần thiết cho tác vụ cụ thể của nó:
| Tài nguyên | Tùy chọn giới hạn |
|---|---|
| Filesystem | Mount chỉ những thư mục cần thiết, ưu tiên read-only |
| Network | Giới hạn tới các endpoint cụ thể qua proxy |
| Credential | Inject qua proxy thay vì expose trực tiếp |
| System capability | Drop Linux capability trong container |
Defense in depth
Phần tiêu đề “Defense in depth”Với môi trường bảo mật cao, xếp chồng nhiều control mang lại bảo vệ bổ sung. Các tùy chọn gồm:
- Container isolation
- Giới hạn network
- Kiểm soát filesystem
- Validate request tại proxy
Sự kết hợp phù hợp phụ thuộc vào threat model và yêu cầu vận hành của bạn.
Công nghệ isolation
Phần tiêu đề “Công nghệ isolation”Các công nghệ isolation khác nhau đem lại đánh đổi khác nhau giữa độ mạnh bảo mật, hiệu năng, và độ phức tạp vận hành.
| Công nghệ | Độ mạnh isolation | Overhead hiệu năng | Độ phức tạp |
|---|---|---|---|
| Sandbox runtime | Tốt (mặc định an toàn) | Rất thấp | Thấp |
| Container (Docker) | Tùy theo cấu hình | Thấp | Trung bình |
| gVisor | Xuất sắc (nếu cấu hình đúng) | Trung bình/Cao | Trung bình |
| VM (Firecracker, QEMU) | Xuất sắc (nếu cấu hình đúng) | Cao | Trung bình/Cao |
Sandbox runtime
Phần tiêu đề “Sandbox runtime”Để có isolation nhẹ mà không cần container, sandbox-runtime enforce giới hạn filesystem và network ở tầng OS.
Ưu điểm chính là sự đơn giản: không cần cấu hình Docker, container image, hay thiết lập networking. Proxy và giới hạn filesystem đã được tích hợp sẵn. Bạn cung cấp một file settings chỉ định domain và path được cho phép.
Cách hoạt động:
- Filesystem: Dùng OS primitive (
bubblewraptrên Linux,sandbox-exectrên macOS) để giới hạn quyền đọc/ghi vào các path đã cấu hình - Network: Loại bỏ network namespace (Linux) hoặc dùng Seatbelt profile (macOS) để route traffic network qua một proxy tích hợp sẵn
- Cấu hình: Allowlist dạng JSON cho domain và filesystem path
Cài đặt:
npm install @anthropic-ai/sandbox-runtimeSau đó tạo một file cấu hình chỉ định path và domain được cho phép.
Lưu ý bảo mật:
-
Chung kernel với host: Không giống VM, các process trong sandbox dùng chung kernel với host. Một lỗ hổng kernel về lý thuyết có thể cho phép escape. Với một số threat model điều này chấp nhận được, nhưng nếu bạn cần isolation ở tầng kernel, dùng gVisor hoặc một VM riêng.
-
Không kiểm tra TLS: Proxy allowlist domain dựa trên hostname client cung cấp và không terminate hay kiểm tra traffic đã mã hóa. Code chạy bên trong sandbox có thể dùng domain fronting hoặc kỹ thuật tương tự để tiếp cận host ngoài allowlist. Nếu threat model của bạn cần đảm bảo mạnh hơn, cấu hình một TLS-terminating proxy. Xem giới hạn bảo mật của sandboxing để biết chi tiết. Ngoài ra, nếu agent có credential cho phép với một domain, đảm bảo nó không thể dùng domain đó để kích hoạt request network khác hay exfiltrate dữ liệu.
Với nhiều use case single-developer và CI/CD, sandbox-runtime nâng chuẩn bảo mật đáng kể với thiết lập tối thiểu. Các phần dưới bao quát container và VM cho các triển khai cần isolation mạnh hơn.
Container
Phần tiêu đề “Container”Container cung cấp isolation qua Linux namespace. Mỗi container có view riêng về filesystem, process tree, và network stack, trong khi dùng chung kernel với host.
Một cấu hình container hardened về bảo mật có thể trông như sau:
docker run \ --cap-drop ALL \ --security-opt no-new-privileges \ --security-opt seccomp=/path/to/seccomp-profile.json \ --read-only \ --tmpfs /tmp:rw,noexec,nosuid,size=100m \ --tmpfs /home/agent:rw,noexec,nosuid,size=500m \ --network none \ --memory 2g \ --cpus 2 \ --pids-limit 100 \ --user 1000:1000 \ -v /path/to/code:/workspace:ro \ -v /var/run/proxy.sock:/var/run/proxy.sock:ro \ agent-imageDưới đây là chức năng của từng tùy chọn:
| Tùy chọn | Mục đích |
|---|---|
--cap-drop ALL | Xóa các Linux capability như NET_ADMIN và SYS_ADMIN có thể cho phép privilege escalation |
--security-opt no-new-privileges | Ngăn process gia tăng quyền qua setuid binary |
--security-opt seccomp=... | Giới hạn syscall khả dụng; mặc định Docker chặn khoảng 44 syscall, profile tùy biến có thể chặn nhiều hơn |
--read-only | Khiến root filesystem của container bất biến, ngăn agent ghi lại thay đổi |
--tmpfs /tmp:... | Cung cấp một thư mục tạm ghi được, bị xóa khi container dừng |
--network none | Xóa toàn bộ network interface; agent giao tiếp qua Unix socket mount bên dưới |
--memory 2g | Giới hạn dùng bộ nhớ để tránh cạn kiệt tài nguyên |
--pids-limit 100 | Giới hạn số process để tránh fork bomb |
--user 1000:1000 | Chạy dưới một user không phải root |
-v ...:/workspace:ro | Mount code read-only để agent phân tích nhưng không sửa được. Tránh mount các thư mục host nhạy cảm như ~/.ssh, ~/.aws, hay ~/.config |
-v .../proxy.sock:... | Mount một Unix socket kết nối tới một proxy chạy bên ngoài container (xem bên dưới) |
Kiến trúc Unix socket:
Với --network none, container hoàn toàn không có network interface. Cách duy nhất để agent tiếp cận thế giới bên ngoài là qua Unix socket được mount, socket này kết nối tới một proxy chạy trên host. Proxy này có thể enforce domain allowlist, inject credential, và log toàn bộ traffic.
Đây là cùng kiến trúc mà sandbox-runtime dùng. Kể cả khi agent bị xâm nhập qua prompt injection, nó cũng không thể exfiltrate dữ liệu tới server tùy ý. Nó chỉ có thể giao tiếp qua proxy, thứ kiểm soát domain nào có thể tiếp cận. Xem thêm chi tiết ở bài blog về sandboxing của Claude Code.
Tùy chọn hardening bổ sung:
| Tùy chọn | Mục đích |
|---|---|
--userns-remap | Map root của container tới user host không có đặc quyền; cần cấu hình daemon nhưng giới hạn thiệt hại từ container escape |
--ipc private | Cô lập inter-process communication để tránh tấn công liên container |
gVisor
Phần tiêu đề “gVisor”Container tiêu chuẩn dùng chung kernel host: khi code trong container thực hiện system call, nó đi thẳng tới cùng kernel chạy host. Điều này có nghĩa là một lỗ hổng kernel có thể cho phép container escape. gVisor giải quyết điều này bằng cách chặn system call ở tầng userspace trước khi chúng chạm tới kernel host, tự triển khai một lớp tương thích xử lý phần lớn syscall mà không cần đến kernel thật.
Nếu một agent chạy code độc hại (có thể do prompt injection), code đó chạy trong container và có thể thử khai thác kernel. Với gVisor, attack surface nhỏ hơn nhiều: code độc hại sẽ cần khai thác triển khai userspace của gVisor trước, và có quyền truy cập hạn chế vào kernel thật.
Để dùng gVisor với Docker, cài runtime runsc và cấu hình daemon:
{ "runtimes": { "runsc": { "path": "/usr/local/bin/runsc" } }}Sau đó chạy container với:
docker run --runtime=runsc agent-imageLưu ý hiệu năng:
| Workload | Overhead |
|---|---|
| Tính toán nặng CPU | ~0% (không chặn syscall) |
| Syscall đơn giản | ~chậm hơn 2 lần |
| I/O file nặng | Chậm hơn tới 10-200 lần với pattern open/close dày đặc |
Với môi trường multi-tenant hoặc khi xử lý nội dung không tin cậy, phần isolation bổ sung thường xứng đáng với overhead.
Virtual machine
Phần tiêu đề “Virtual machine”VM cung cấp isolation ở tầng phần cứng qua CPU virtualization extension. Mỗi VM chạy kernel riêng, tạo ra một ranh giới mạnh. Một lỗ hổng trong guest kernel không trực tiếp làm tổn hại host. Tuy nhiên, VM không tự động “an toàn hơn” các lựa chọn thay thế như gVisor. Bảo mật của VM phụ thuộc nhiều vào hypervisor và code mô phỏng thiết bị.
Firecracker được thiết kế cho isolation microVM nhẹ. Nó có thể boot VM trong dưới 125ms với overhead bộ nhớ dưới 5 MiB, loại bỏ mô phỏng thiết bị không cần thiết để giảm attack surface.
Với cách tiếp cận này, VM agent không có network interface bên ngoài. Thay vào đó, nó giao tiếp qua vsock (virtual socket). Toàn bộ traffic route qua vsock tới một proxy trên host, proxy này enforce allowlist và inject credential trước khi forward request.
Triển khai cloud
Phần tiêu đề “Triển khai cloud”Với triển khai cloud, bạn có thể kết hợp bất kỳ công nghệ isolation nào ở trên với network control cloud-native:
- Chạy agent container trong một private subnet không có internet gateway
- Cấu hình cloud firewall rule (AWS Security Group, GCP VPC firewall) để chặn toàn bộ egress trừ tới proxy của bạn
- Chạy một proxy (như Envoy với filter
credential_injector) validate request, enforce domain allowlist, inject credential, và forward tới API bên ngoài - Cấp quyền IAM tối thiểu cho service account của agent, route truy cập nhạy cảm qua proxy khi có thể
- Log toàn bộ traffic tại proxy phục vụ audit
Quản lý credential
Phần tiêu đề “Quản lý credential”Agent thường cần credential để gọi API, truy cập repository, hoặc tương tác với dịch vụ cloud. Thách thức là cung cấp truy cập này mà không expose chính credential.
Pattern proxy
Phần tiêu đề “Pattern proxy”Cách tiếp cận được khuyến nghị là chạy một proxy bên ngoài security boundary của agent, inject credential vào outgoing request. Agent gửi request không kèm credential, proxy thêm credential vào, và forward request tới đích.
Pattern này có nhiều lợi ích:
- Agent không bao giờ thấy credential thật
- Proxy có thể enforce một allowlist các endpoint được phép
- Proxy có thể log mọi request phục vụ audit
- Credential được lưu ở một nơi bảo mật duy nhất thay vì phân tán tới từng agent
Cấu hình Claude Code dùng proxy
Phần tiêu đề “Cấu hình Claude Code dùng proxy”Claude Code hỗ trợ hai phương thức để route sampling request qua một proxy:
Tùy chọn 1: ANTHROPIC_BASE_URL (đơn giản nhưng chỉ cho sampling API request)
export ANTHROPIC_BASE_URL="http://localhost:8080"Điều này báo Claude Code và Agent SDK gửi sampling request tới proxy của bạn thay vì thẳng tới Claude API. Proxy của bạn nhận HTTP request dạng plaintext, có thể kiểm tra và sửa chúng (kể cả inject credential), rồi forward tới API thật.
Tùy chọn 2: HTTP_PROXY / HTTPS_PROXY (toàn hệ thống)
export HTTP_PROXY="http://localhost:8080"export HTTPS_PROXY="http://localhost:8080"Claude Code và Agent SDK tôn trọng các biến môi trường chuẩn này, route toàn bộ traffic HTTP qua proxy. Với HTTPS, proxy tạo một encrypted CONNECT tunnel: nó không thể thấy hay sửa nội dung request nếu không có TLS interception.
Triển khai một proxy
Phần tiêu đề “Triển khai một proxy”Bạn có thể tự xây proxy hoặc dùng proxy có sẵn:
- Envoy Proxy: proxy cấp production với filter
credential_injectorđể thêm header auth - mitmproxy: proxy TLS-terminating để kiểm tra và sửa traffic HTTPS
- Squid: caching proxy với access control list
- LiteLLM: LLM gateway với credential injection và rate limiting
Credential cho dịch vụ khác
Phần tiêu đề “Credential cho dịch vụ khác”Ngoài sampling từ Claude API, agent thường cần truy cập được xác thực tới các dịch vụ khác, như git repository, database, và internal API. Có hai cách tiếp cận chính:
Custom tool
Phần tiêu đề “Custom tool”Cung cấp quyền truy cập qua một MCP server hoặc custom tool route request tới một dịch vụ chạy bên ngoài security boundary của agent. Agent gọi tool, nhưng request được xác thực thật sự xảy ra bên ngoài. Tool gọi tới một proxy inject credential.
Ví dụ, một git MCP server có thể nhận lệnh từ agent nhưng forward chúng tới một git proxy chạy trên host, proxy này thêm authentication trước khi liên hệ remote repository. Agent không bao giờ thấy credential.
Ưu điểm:
- Không cần TLS interception: Dịch vụ bên ngoài thực hiện request đã xác thực trực tiếp
- Credential nằm ngoài: Agent chỉ thấy interface của tool, không thấy credential bên dưới
Chuyển tiếp traffic
Phần tiêu đề “Chuyển tiếp traffic”Với lời gọi Claude API, ANTHROPIC_BASE_URL cho phép bạn route request tới một proxy có thể kiểm tra và sửa chúng dạng plaintext. Nhưng với các dịch vụ HTTPS khác (GitHub, npm registry, internal API), traffic thường được mã hóa end-to-end. Kể cả nếu bạn route nó qua một proxy bằng HTTP_PROXY, proxy chỉ thấy một tunnel TLS mờ đục và không thể inject credential.
Để sửa traffic HTTPS tới các dịch vụ tùy ý, mà không dùng custom tool, bạn cần một TLS-terminating proxy giải mã traffic, kiểm tra hoặc sửa nó, rồi mã hóa lại trước khi forward. Điều này đòi hỏi:
- Chạy proxy bên ngoài container của agent
- Cài chứng chỉ CA của proxy vào trust store của agent (để agent tin tưởng chứng chỉ của proxy)
- Cấu hình
HTTP_PROXY/HTTPS_PROXYđể route traffic qua proxy
Cách tiếp cận này xử lý mọi dịch vụ dựa trên HTTP mà không cần viết custom tool, nhưng thêm độ phức tạp về quản lý chứng chỉ.
Lưu ý không phải mọi chương trình đều tôn trọng HTTP_PROXY/HTTPS_PROXY. Đa số công cụ (curl, pip, npm, git) có tôn trọng, nhưng một số có thể bỏ qua các biến này và kết nối trực tiếp. Ví dụ, Node.js fetch() bỏ qua các biến này theo mặc định; từ Node 24+ bạn có thể set NODE_USE_ENV_PROXY=1 để bật hỗ trợ. Để bao phủ toàn diện, bạn có thể dùng proxychains để chặn network call, hoặc cấu hình iptables để redirect outbound traffic tới một transparent proxy.
Cả hai cách tiếp cận vẫn cần TLS-terminating proxy và chứng chỉ CA đáng tin. Chúng chỉ đảm bảo traffic thực sự tới được proxy.
Cấu hình filesystem
Phần tiêu đề “Cấu hình filesystem”Kiểm soát filesystem quyết định file nào agent có thể đọc và ghi.
Mount code read-only
Phần tiêu đề “Mount code read-only”Khi agent cần phân tích code nhưng không sửa nó, mount thư mục read-only:
docker run -v /path/to/code:/workspace:ro agent-imageVị trí ghi được
Phần tiêu đề “Vị trí ghi được”Nếu agent cần ghi file, bạn có vài tùy chọn tùy theo bạn có muốn thay đổi được lưu lại lâu dài hay không:
Với workspace tạm thời trong container, dùng mount tmpfs chỉ tồn tại trong bộ nhớ và bị xóa khi container dừng:
docker run \ --read-only \ --tmpfs /tmp:rw,noexec,nosuid,size=100m \ --tmpfs /workspace:rw,noexec,size=500m \ agent-imageNếu bạn muốn review thay đổi trước khi lưu lại lâu dài, một overlay filesystem cho phép agent ghi mà không sửa file gốc bên dưới. Thay đổi được lưu trong một layer riêng bạn có thể kiểm tra, áp dụng, hoặc bỏ. Với output hoàn toàn lâu dài, mount một volume riêng nhưng giữ nó tách biệt với các thư mục nhạy cảm.
Đọc thêm
Phần tiêu đề “Đọc thêm”lượt xem