Hôm qua tôi bảo Claude Code “refactor auth module to use JWT with refresh tokens”, AI phân tích 8 files liên quan, generate middleware, repository, và test suite trong 15 phút. Việc thường mất tôi cả buổi sáng.
Rồi thực tế ập đến: đây là production app với Stripe secret keys trong .env, AWS credentials trong docker-compose.yml, proprietary pricing algorithms trong src/services/pricing/, và hardcoded database passwords nằm rải rác. Tôi muốn năng suất của Claude Code, nhưng không thể giao toàn bộ secrets cho một AI.
Cách thận trọng nhất tôi thử đầu tiên — tạo demo project sạch, copy code qua lại bằng tay — an toàn nhưng giết năng suất. Ngược lại với lý do tôi dùng Claude Code. Vài tháng sau, tôi đã thử qua 4 chiến lược khác nhau, mỗi cái có trade-off riêng. Đây là toàn bộ chúng, xếp hạng theo bảo mật, tốc độ, và độ bền hàng ngày.
Claude Code thực sự “thấy” gì
Trước khi đi vào chiến lược, clarify một điều: Claude Code không tự động scan toàn bộ project của bạn. Nó request permission để đọc file, bạn approve hoặc deny. Có thể tin tưởng được — nếu bạn deny access đến .env, nó không đọc.
Nhưng rủi ro thật nằm ở đây: khi Claude Code cần hiểu kiến trúc hoặc debug lỗi phức tạp, nó request đọc file gần code nhạy cảm. Ranh giới giữa “vô hại” và “chứa secret” không luôn rõ ràng.
Ví dụ thực tế:
# Files AN TOÀN cho Claude Code đọc:src/services/payment.service.ts # TypeScript interfaceapp/api/users/route.ts # Next.js API routelib/repositories/user_repo.dart # Flutter repositorySources/Services/UserService.swift # iOS service protocol
# Files CHỨA SECRETS — nguy hiểm:.env # DATABASE_URL, API keys.env.local # Development overridesdocker-compose.yml # DB passwords, service tokenssrc/config/stripe.ts # Hardcoded keysgoogle-services.json # Android FirebaseGoogleService-Info.plist # iOS Firebasecredentials.json # GCP service accountCode interface vô hại vs config chứa secrets:
// src/services/payment.service.ts — interface vô hại ✅export interface PaymentService { charge(amount: number, currency: string): Promise<PaymentResult>; refund(transactionId: string): Promise<void>;}
// src/config/stripe.ts — chứa secret ❌export const stripeConfig = { publishableKey: "pk_live_...", // OK để public secretKey: process.env.STRIPE_SECRET_KEY, // OK nếu đọc từ .env webhookSecret: "whsec_live_abc123...", // hardcoded! nguy hiểm};Khi Claude Code thấy error trong payment flow, nó muốn đọc cả hai file. Bạn có chắc luôn bắt được lúc approve hay không?
Đây là lý do tôi thử các chiến lược ngăn chặn vật lý thay vì chỉ dựa vào approve từng file.
Chiến lược 1: Demo Project — Copy bằng “cơm”
Cách hoạt động: Tạo project trắng, copy file cần sửa sang đó, để Claude Code xử lý, rồi copy output ngược lại project thật.
Project thật Demo project sạch ↓ copy ↓File A (có secret) File A (xóa secret) ↓ ↓(không chạm) Claude Code edit ↓ copy ngược ↓File A (merge bằng tay) File A (output)Trải nghiệm thực tế: Đây là cách đầu tiên tôi thử. An toàn tuyệt đối — Claude Code không bao giờ thấy project thật. Nhưng overhead quá khủng khiếp. Một task “add rate limiting to API endpoints” trở thành:
- Copy
routes/api.ts,middleware/rateLimit.ts,config/redis.tssang demo project (2 phút) - Xóa import từ proprietary modules, fake Redis config (5 phút)
- Chạy Claude Code, output OK (3 phút)
- Copy output ngược, merge conflict bằng tay (10 phút)
- Fix import, dependencies, compile errors (15 phút)
Một task 5 phút trở thành 35 phút. Overhead tệ nhưng chưa phải tệ nhất — chất lượng output tệ hơn. Demo project không có đầy đủ context: không có database schemas, không có shared types, không có existing middleware stack. Claude Code generate code hoàn toàn đúng về syntax nhưng sai về architecture vì nó không thấy cách phần còn lại của app hoạt động.
| Tiêu chí | Đánh giá |
|---|---|
| Bảo mật | ⭐⭐⭐⭐⭐ — Hoàn toàn cô lập |
| Tốc độ | ⭐ — Overhead 6-7x |
| Chất lượng output | ⭐⭐ — Context nghèo nàn |
| Bền vững hàng ngày | ⭐ — Quá tốn thời gian |
Phù hợp khi: Một lần fix quick bug trên code cực nhạy cảm và không bao giờ lặp lại.
Chiến lược 2: Duplicate Project + Git Patch
Cách hoạt động: Clone project thật, xóa secrets, thêm fake config, làm việc với Claude Code ở đó, sync thay đổi về project thật bằng git patch.
# One-time setupgit clone project.git project-claudecd project-claude
# Script tự động xóa secrets./scripts/remove-secrets.shScript cleanup universal (remove-secrets.sh):
#!/bin/bash# Remove all sensitive filesrm -f .env .env.local .env.productionrm -f docker-compose.prod.ymlrm -f credentials.json service-account.jsonfind . -name "google-services.json" -deletefind . -name "GoogleService-Info.plist" -deletefind . -name "*.keystore" -deletefind . -name "*.jks" -deletefind . -name "*.pem" -deletefind . -name "*.p12" -delete
# Add dummy configsecho "DATABASE_URL=postgres://user:pass@localhost:5432/mydb" > .envecho "STRIPE_SECRET_KEY=sk_test_DUMMY_DO_NOT_USE" >> .envecho "AWS_ACCESS_KEY_ID=DUMMY" >> .envecho "OPENAI_API_KEY=sk-test-FAKE" >> .env
git add -A && git commit -m "Sanitize for Claude Code"Daily workflow:
# Làm việc trong project-claudecd ~/projects/project-claude# ... Claude Code edit files ...git diff main > changes.patch
# Apply vào project thậtcd ~/projects/projectgit apply changes.patchTrải nghiệm thực tế: Đây là cải thiện lớn. Tôi có full context — toàn bộ API routes, database models, middleware stack, shared utilities. Claude Code thấy đủ để generate code follow đúng patterns của app. Secrets bị remove vật lý ở workspace khác, nên không có cách nào Claude Code đọc được.
Sync bằng patch hiệu quả hơn copy thủ công 10 lần. Nhưng vẫn có ma sát: mỗi khi project thật nhận update từ team, tôi phải pull ở cả hai workspace và đảm bảo sanitization vẫn đúng. Nếu ai đó thêm secret mới (ví dụ thêm Twilio API key), tôi phải nhớ update script cleanup.
Sau một tháng, tôi có script automation hoàn chỉnh để sync và sanitize. Hoạt động tốt nhưng vẫn phải quản lý hai workspace, hai git states.
| Tiêu chí | Đánh giá |
|---|---|
| Bảo mật | ⭐⭐⭐⭐⭐ — Cô lập vật lý |
| Tốc độ | ⭐⭐⭐⭐ — Chỉ overhead nhẹ |
| Chất lượng output | ⭐⭐⭐⭐ — Gần đầy đủ context |
| Bền vững hàng ngày | ⭐⭐⭐ — Cần automation |
Phù hợp khi: Bạn có thời gian setup script automation và cần bảo mật chắc chắn. Cân bằng tốt.
Chiến lược 3: .claudeignore trên Project thật
Cách hoạt động: Làm việc trực tiếp trên project thật, dùng .claudeignore để chặn Claude Code đọc file nhạy cảm. Zero overhead.
# .claudeignore — Universal secrets protection
# Environment variables.env**.env
# Cloud credentialscredentials.jsonservice-account.json*.pem*.key*.p12
# Mobile platform configsgoogle-services.jsonGoogleService-Info.plistlocal.properties
# Keystores & certificates*.keystore*.jks*.pfx
# Infrastructure configsdocker-compose.prod.ymlkubernetes/secrets.yaml**/vault/****/secrets/**
# Proprietary business logicsrc/**/trading/**src/**/pricing-engine/**src/**/recommendation-algorithm/**
# Build artifacts & dependenciesnode_modules/dist/build/.next/__pycache__/target/vendor/Trải nghiệm thực tế: Nhanh nhất, output tốt nhất, overhead bằng không. Khi bạn cần fix bug, bạn chỉ cần nói với Claude Code. Nó thấy đầy đủ context — architecture, dependencies, patterns — nhưng bị chặn không đọc secrets.
Nhưng tôi phải thành thật về e ngại của mình: đây là ranh giới phần mềm, không phải vật lý. Files vẫn nằm trên ổ đĩa. Tôi tin Anthropic, nhưng tôi không thể verify 100% rằng .claudeignore không bao giờ bị bypass — do bug, do misconfiguration, hoặc do edge case tôi chưa nghĩ ra.
Ví dụ: nếu một file không trong .claudeignore import constants từ file bị ignore, và Claude Code cần hiểu constant đó để fix bug, điều gì sẽ xảy ra? Nó có request đọc file được import không? Tôi không chắc.
Vì vậy tôi dùng chiến lược này cho project cá nhân hoặc side project không có secrets nghiêm trọng. Với production app có real payment keys và production database URLs, tôi chưa yên tâm 100%.
| Tiêu chí | Đánh giá |
|---|---|
| Bảo mật | ⭐⭐⭐ — Tin tưởng implementation |
| Tốc độ | ⭐⭐⭐⭐⭐ — Zero overhead |
| Chất lượng output | ⭐⭐⭐⭐⭐ — Đầy đủ context |
| Bền vững hàng ngày | ⭐⭐⭐⭐⭐ — Workflow tự nhiên |
Phù hợp khi: Bạn chấp nhận ranh giới phần mềm. Hoặc project không chứa secrets cực nhạy cảm. Hoặc chính sách công ty cho phép.
Chiến lược 4: Git Worktree + Clean Branch
Cách hoạt động: Dùng git worktree tạo working directory thứ hai trên branch sạch không có secrets. Cùng một repo, hai folders. Bảo mật vật lý + sync hiệu quả.
# One-time setupcd ~/projects/my-appgit worktree add ../my-app-claude clean-branch
# Ở clean-branch:cd ~/projects/my-app-claude./scripts/remove-secrets.shgit add -A && git commit -m "Sanitize: remove all secrets"
# Daily workflowcd ~/projects/my-app-claude # Worktree sạch# ... Claude Code edit ...git add -A && git commit -m "Add email verification flow"
# Sync về maincd ~/projects/my-app # Project thậtgit cherry-pick <commit-hash> # Chọn commits muốn apply
# Hoặc test trước khi mergenpm test # Verify trong project thật# pytest # Python# go test ./... # Go# ./gradlew test # Android/Java# swift test # iOSTrải nghiệm thực tế: Đây là giải pháp thanh lịch mà ít developer biết. Git worktree cho phép checkout hai branches của cùng một repo vào hai folders khác nhau. Không phải clone, không phải duplicate — cùng một .git, hai working directories.
Setup: tôi tạo branch claude-clean, xóa tất cả secrets, commit fake configs. Branch này không bao giờ merge vào main. Mỗi khi làm việc với Claude Code, tôi checkout worktree vào folder riêng:
~/projects/ my-app/ ← main branch (có secrets) my-app-claude/ ← claude-clean branch (không secrets)Khi Claude Code xong, tôi cherry-pick commit từ claude-clean vào main. Git đủ thông minh để apply code changes mà không apply secret deletions. Nếu có conflict ở secret files, tôi chỉ cần skip.
Ưu điểm lớn: bảo mật vật lý giống Chiến lược 2, nhưng không phải quản lý hai repos. Sync dễ dàng hơn nhiều vì cùng git history. Tôi thậm chí có thể rebase claude-clean lên main thường xuyên để giữ nó updated.
Nhược điểm: cần thành thạo git. Nếu chưa quen cherry-pick, rebase, hoặc worktree, learning curve hơi dốc.
| Tiêu chí | Đánh giá |
|---|---|
| Bảo mật | ⭐⭐⭐⭐⭐ — Cô lập vật lý |
| Tốc độ | ⭐⭐⭐⭐ — Cherry-pick rất nhanh |
| Chất lượng output | ⭐⭐⭐⭐⭐ — Đầy đủ context |
| Bền vững hàng ngày | ⭐⭐⭐⭐ — Khi đã quen git |
Phù hợp khi: Bạn comfortable với git worktree. Muốn bảo mật vật lý mà vẫn workflow gần như tự nhiên.
So sánh nhanh
| Chiến lược | Bảo mật | Tốc độ | Context | Setup | Best for |
|---|---|---|---|---|---|
| Demo project | Cao nhất | Chậm nhất | Nghèo | Dễ | One-off tasks |
| Duplicate + patch | Cao | Tốt | Đầy đủ | Trung bình | Automation-friendly workflow |
.claudeignore | Trung bình | Nhanh nhất | Đầy đủ | Dễ nhất | Projects không quá nhạy cảm |
| Git worktree | Cao | Tốt | Đầy đủ | Cần hiểu git | Production apps + git fluent |
Files cần bảo vệ theo platform
| File / Pattern | Platforms | Lý do |
|---|---|---|
.env, .env.* | Tất cả | API keys, DB URLs, secrets |
docker-compose.prod.yml | Backend, fullstack | Production passwords |
credentials.json | GCP (all platforms) | Service account keys |
google-services.json | Android | Firebase config với API keys |
GoogleService-Info.plist | iOS | Firebase config cho iOS |
*.keystore, *.jks | Android, Java | App signing keys |
*.pem, *.p12, *.pfx | iOS, SSL, certificates | Private keys |
secrets.yaml | Kubernetes | Infrastructure secrets |
local.properties | Android | SDK paths, signing configs |
xcconfig files | iOS | Build settings với tokens |
Đề xuất — Chọn theo mức độ chấp nhận rủi ro
- Bạn paranoid về security: Git worktree (#4) hoặc Duplicate + patch (#2)
- Bạn cần năng suất tối đa:
.claudeignore(#3) — nhưng audit.claudeignorethường xuyên - Bạn chưa quen git worktree: Duplicate + patch (#2) + viết script automation
- Chỉ cần dùng Claude Code một lần: Demo project (#1) OK, đừng mong workflow lâu dài
Bonus: CLAUDE_CONTEXT.md cho phép Claude Code biết những gì nó KHÔNG được thấy
Dù dùng chiến lược nào, tôi recommend thêm file CLAUDE_CONTEXT.md hoặc CLAUDE.md nói rõ những gì bị ẩn và cách truy cập đúng.
Next.js / TypeScript Example:
## Tech Stack- Next.js 14 + TypeScript + Prisma + PostgreSQL- Stripe for payments- AWS S3 for file storage
## Secrets (hidden from Claude Code)- `.env.local` contains: - DATABASE_URL (Postgres connection) - STRIPE_SECRET_KEY - AWS_ACCESS_KEY_ID & AWS_SECRET_ACCESS_KEY - NEXTAUTH_SECRET
## How to reference secrets in code- Always use `process.env.VARIABLE_NAME`- NEVER hardcode keys- NEVER commit .env files- For client-side: prefix with `NEXT_PUBLIC_` (but avoid secrets there)
## Example:```typescript// ✅ Correctconst stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { apiVersion: '2023-10-16',});
// ❌ Wrongconst stripe = new Stripe('sk_live_abc123...', { apiVersion: '2023-10-16',});### Python / FastAPI Example:
```markdown## Tech Stack- FastAPI + SQLAlchemy + PostgreSQL- Redis for caching- AWS for infrastructure
## Secrets (hidden from Claude Code)- `.env` loaded by python-dotenv- Contains: DATABASE_URL, REDIS_URL, AWS credentials, API keys
## How to reference secrets- All secrets accessed via `settings.py` Pydantic BaseSettings- NEVER hardcode secrets- Use `settings.DATABASE_URL` not direct os.getenv()
## Example:```python# ✅ Correctfrom app.config import settings
engine = create_engine(settings.DATABASE_URL)
# ❌ Wrongengine = create_engine("postgresql://user:password@localhost/db")### Mobile (KMP / React Native) Example:
```markdown## Tech Stack- Kotlin Multiplatform (KMP) shared code- Android: Jetpack Compose- iOS: SwiftUI
## Secrets (hidden from Claude Code)- Android: `local.properties` (API keys, SDK paths)- iOS: `Config.xcconfig` files- Shared: `gradle.properties` for signing
## How to reference secrets- Android: Use BuildConfig constants- iOS: Use Info.plist or xcconfig variables- NEVER commit keystore files or signing certificates
## Example:```kotlin// ✅ Correct (Android)val apiKey = BuildConfig.API_KEY
// ❌ Wrongval apiKey = "sk-abc123xyz"Điều này giúp Claude Code generate code đúng cấu trúc — nó biết phải dùng `process.env.STRIPE_SECRET_KEY` hoặc `BuildConfig.API_KEY` thay vì hardcode, dù không thấy file chứa key.
---
## Kết luận
Hành trình của tôi: bắt đầu với Demo project (quá chậm), chuyển sang Duplicate + patch (tốt hơn nhiều), thử `.claudeignore` (nhanh nhất nhưng lo ngại bảo mật), cuối cùng settle ở Git worktree (cân bằng tốt nhất cho workflow của tôi).
Bạn không cần theo đúng con đường đó. Chọn chiến lược fit với risk tolerance và git comfort level của bạn. Điều quan trọng nhất: đừng bỏ qua bảo mật vì năng suất. Claude Code là force multiplier, nhưng chỉ khi bạn dùng nó trên nền tảng an toàn.
Dù chọn cách nào, thêm `CLAUDE_CONTEXT.md`. Nó giúp AI hiểu những gì nó không thấy.
---
*Muốn đi sâu hơn? [Khóa học Claude Code Mastery](/) cover tất cả — bao gồm module bảo mật hoàn chỉnh (Phase 2) với bài tập thực hành. Phases 1-3 hoàn toàn miễn phí.*
*Nhận [Claude Code Cheat Sheet miễn phí](/products) — 50+ commands trong một file PDF — khi đăng ký newsletter.*