Tips

Bảo vệ API key khi build app AI: 7 lỗi khiến hoá đơn tăng vọt sau một đêm

Tóm tắt

Không bao giờ để API key ở frontend, repo hay ảnh chụp màn hình. Đặt key ở server/secret manager, gọi model qua backend của bạn, giới hạn chi tiêu, tách key theo môi trường và xoay key định kỳ. Lộ key → thu hồi ngay, rồi mới điều tra.

Câu chuyện quen thuộc trong các group dev: build xong app AI, deploy tối thứ Sáu, sáng thứ Hai mở email thấy hoá đơn API vài nghìn đô. Nguyên nhân gần như luôn giống nhau — API key bị lộ, và ai đó (thường là bot quét tự động) đã dùng nó cả cuối tuần. Bài này tổng hợp 7 lỗi phổ biến nhất, cách sửa từng lỗi, cách chặn coding agent đọc nhầm file bí mật, và quy trình xử lý khi key đã lộ.

Vì sao key AI bị lộ nhanh hơn bạn nghĩ?

API key của nhà cung cấp LLM là “tiền mặt”: ai cầm được là dùng được ngay, không cần đăng nhập, không cần xác minh. Các bot liên tục quét GitHub công khai, bundle JavaScript của website, app mobile đã giải nén để tìm chuỗi có dạng key. Key lọt lên repo public có thể bị khai thác trong vài phút. Với app AI, thiệt hại không chỉ là tiền: người lạ có thể dùng tài khoản của bạn để tạo nội dung vi phạm, khiến tài khoản bị khoá.

7 lỗi hay gặp và cách sửa

LỗiVì sao nguy hiểmCách sửa
1. Key nằm trong code frontend / app mobileMọi thứ gửi xuống trình duyệt hay đóng gói trong app đều đọc được — kể cả khi đã minify hay obfuscateGọi model qua backend hoặc serverless function của bạn; client chỉ gọi API của bạn, có xác thực người dùng
2. Commit file .env lên GitXoá ở commit sau vẫn còn trong lịch sử; fork và clone đã có bản saoThêm .env* vào .gitignore; bật secret scanning và push protection trên GitHub
3. Một key dùng cho mọi môi trườngLộ key dev = lộ luôn production; không biết chi phí đến từ đâuTách key dev / staging / prod / CI, đặt tên rõ ràng; mỗi môi trường một Workspace nếu được
4. Không có spend limitKhông có gì chặn hoá đơn khi bị lạm dụngĐặt hạn mức chi tiêu và cảnh báo email trong Console cho từng Workspace
5. Dán key vào chat, ticket, ảnh chụpSlack, Jira, ảnh màn hình được lưu lâu, nhiều người xem, có thể bị indexChia sẻ qua secret manager / vault (1Password, Vault, AWS Secrets Manager…)
6. Coding agent đọc được file chứa keyKey có thể bị đưa vào context, log, hoặc bị prompt injection lừa gửi ra ngoàiChặn đọc file bí mật bằng permission deny, hook, hoặc sandbox (xem phần dưới)
7. Không bao giờ xoay keyKey cũ của người đã nghỉ việc, máy cũ, CI cũ vẫn sốngXoay định kỳ và ngay khi có người rời team hoặc nghi ngờ lộ

Kiến trúc đúng: client không bao giờ chạm tới key

[Trình duyệt / App]  --(token đăng nhập của user)-->  [Backend của bạn]
                                                        |  kiểm tra quyền, rate limit theo user,
                                                        |  ghi log chi phí theo user
                                                        v
                                               [API Claude]  (key nằm ở server / secret manager)

Backend là nơi bạn kiểm soát: ai được gọi, gọi bao nhiêu lần, prompt nào được phép. Đây cũng là nơi đặt rate limit theo từng người dùng để một tài khoản bị chiếm không đốt cả ngân sách.

Bật “lưới an toàn” trên GitHub

  • Secret scanning quét repo để phát hiện chuỗi giống key của các nhà cung cấp được hỗ trợ và tạo cảnh báo.
  • Push protection chặn ngay lúc git push nếu phát hiện secret, trước khi nó kịp lên server. Người push phải sửa commit hoặc ghi lý do để bỏ qua.
  • Với repo public, các tính năng này có sẵn; với repo private của tổ chức, kiểm tra gói GitHub đang dùng.

Đây là lưới an toàn, không phải chiến lược chính — công cụ chỉ nhận diện được các định dạng key đã biết.

Chặn coding agent đọc file bí mật

Khi dùng Claude Code, bạn có thể khai báo quy tắc từ chối trong .claude/settings.json (commit cùng repo để cả team dùng):

{
  "permissions": {
    "deny": [
      "Read(**/.env)",
      "Read(**/.env.*)",
      "Read(./secrets/**)"
    ]
  }
}

Ba điều cần biết để không bị an tâm giả:

  1. Deny Read không chặn Bash. Lệnh như cat .env vẫn có thể đọc file nếu được duyệt. Hãy giữ Bash ở chế độ hỏi trước, hoặc chặn thêm các lệnh đọc file đó.
  2. Read và Write là hai quy tắc riêng. Chặn đọc không đồng nghĩa với chặn ghi đè.
  3. Muốn chắc chắn hơn, bật sandbox của Claude Code (/sandbox) để cô lập hệ thống file và mạng ở cấp hệ điều hành, hoặc chạy trong dev container. Với tổ chức, đặt các quy tắc deny quan trọng trong managed settings để người dùng không ghi đè được.

Cách tốt nhất vẫn là: máy dev không giữ key production. Dev dùng key riêng có hạn mức thấp; key production chỉ nằm trong secret manager của môi trường chạy.

Khi key đã lộ: làm theo đúng thứ tự

  1. Thu hồi (revoke) key ngay trong Console — trước khi làm bất cứ việc gì khác. Mỗi phút chờ là thêm chi phí.
  2. Tạo key mới, cập nhật vào secret manager và các môi trường cần dùng.
  3. Xem usage log để đánh giá thiệt hại: thời điểm bắt đầu bất thường, model bị gọi, khối lượng token.
  4. Xoá key khỏi lịch sử Git nếu cần — nhưng coi như key cũ đã mất vĩnh viễn, vì đã có người sao chép.
  5. Liên hệ nhà cung cấp nếu có chi phí phát sinh bất thường, kèm mốc thời gian và bằng chứng.
  6. Viết postmortem ngắn: key lộ qua đâu, vì sao không bị chặn sớm, thêm biện pháp nào.

Checklist trước khi deploy app AI

  • Không có key nào trong bundle frontend hay app mobile (tìm thử chuỗi key trong file build).
  • .env* đã nằm trong .gitignore; push protection đã bật.
  • Key production nằm trong secret manager, tách khỏi key dev và CI.
  • Spend limit và cảnh báo đã đặt cho Workspace production.
  • Backend có rate limit theo người dùng và ghi log chi phí.
  • Có người chịu trách nhiệm và quy trình xoay key.

Áp dụng thế nào?

  • Dev: Chạy lại checklist trên với app hiện tại hôm nay — mất 15 phút nhưng có thể tiết kiệm một hoá đơn bất ngờ.
  • Tech Lead: Đưa quy tắc deny cho file bí mật vào .claude/settings.json của mọi repo, và thêm mục “không có secret trong client” vào checklist code review.
  • PM: Yêu cầu mỗi dự án AI có spend limit và người nhận cảnh báo chi phí ngay từ sprint đầu, giống như yêu cầu có monitoring.

Nguồn & tham khảo

  1. Security — Claude Code Docs
  2. Claude Code Permissions — Pete Freitag
  3. Working with secret scanning and push protection — GitHub Docs