Vibe Code
Giáo trình/Phần 2 — Nền móng Git & GitHub

Bí mật, token và những thứ không bao giờ commit

Bốn chỗ để khóa bí mật và chỗ nào dùng khi nào, cách xử lý khi đã rò rỉ, và ranh giới không đưa mật khẩu cho AI.

Cấp 220 phút đọc

Đây là bài ngắn nhất Cấp 2 và là bài gây thiệt hại nhiều nhất nếu bỏ qua. Bot quét GitHub tìm khóa API liên tục; một khóa lọt lên repo công khai thường bị dùng trong vòng vài phút, không phải vài ngày.

Bốn chỗ giữ bí mật, dùng đúng chỗ

Chỗ Dùng cho Lệnh/đường
.dev.vars (máy bạn) Chạy thử tại máy File, phải có trong .gitignore
Worker Secrets App đang chạy thật wrangler secret put TEN
GitHub Secrets CI/CD (Actions) gh secret set TEN
Trình quản lý mật khẩu Mật khẩu của bạn Không nằm trong project

Nguyên tắc một câu: bí mật đi theo môi trường, không đi theo mã nguồn. Cùng một tên biến ANTHROPIC_API_KEY, giá trị khi chạy ở máy bạn và khi chạy thật là hai giá trị khác nhau, và không giá trị nào nằm trong Git.

Chạy thử tại máy: .dev.vars

Với Workers, wrangler dev tự đọc file .dev.vars ở gốc project:

ANTHROPIC_API_KEY=sk-ant-...
MAT_KHAU_ADMIN=...
ZALO_WEBHOOK=https://...

Và trong mã, bạn đọc qua env:

export default {
  async fetch(request, env) {
    const key = env.ANTHROPIC_API_KEY;   // không bao giờ viết thẳng khóa ở đây
    // ...
  }
};

Hai việc bắt buộc, làm ngay khi tạo file:

echo ".dev.vars" >> .gitignore
git check-ignore -v .dev.vars     # phải in ra dòng khẳng định nó bị bỏ qua

Lệnh thứ hai là lệnh kiểm. Đừng tin là đã an toàn chỉ vì đã gõ dòng đầu.

App chạy thật: Worker Secrets

wrangler secret put ANTHROPIC_API_KEY
# nó hỏi giá trị, bạn tự dán, giá trị không vào lịch sử dòng lệnh
wrangler secret list

Bí mật nằm được mã hóa phía Cloudflare. Sau khi nạp, bạn không đọc lại được — chỉ xem được tên, không xem được giá trị. Đó là tính năng, không phải thiếu sót.

Phân biệt `vars` và `secret` trong `wrangler.toml`

Trong wrangler.toml có mục [vars]:

[vars]
TEN_CONG_TY = "Chang An"
SO_TRANG_MOI_LAN = "50"

Mục này nằm trong Git và hiện trên dashboard. Nó dùng cho cấu hình không bí mật. Nhét khóa API vào đây là rò rỉ, dù app vẫn chạy bình thường nên bạn không hề thấy gì sai.

Luật phân biệt dễ nhớ: nếu giá trị đó mất là phải đổi, nó là secret. Nếu mất cũng không sao, nó là var.

CI/CD: GitHub Secrets

gh secret set CLOUDFLARE_API_TOKEN
gh secret list

Trong workflow dùng qua ${{ secrets.TEN }}. GitHub tự che giá trị trong log — nhưng chỉ che khi khớp nguyên văn. Nếu bạn echo nó ra sau khi biến đổi (cắt chuỗi, mã base64), phần che không còn hiệu lực. Luật: đừng in biến bí mật ra log, dù để gỡ lỗi.

Danh sách thứ không bao giờ commit

.dev.vars          .env, .env.local
*.pem, *.key       chứng chỉ, khóa riêng
wrangler.toml      <- CHỈ KHI bạn viết secret lẫn vào đây (đừng làm vậy)
*.sqlite, *.db     cơ sở dữ liệu có dữ liệu thật
*.xlsx, *.csv      dữ liệu khách hàng đã xuất ra
anh-nhan-vien/     ảnh người thật
.wrangler/         thư mục tạm của wrangler

Bốn dòng giữa là thứ người ta hay quên vì chúng không trông như bí mật. Một file danh-sach-nhan-vien.xlsx để trong project và commit lên là một vụ rò rỉ dữ liệu cá nhân — nặng hơn mất một khóa API, vì khóa thì đổi được còn dữ liệu người khác thì không.

Rò rỉ hay gặp nhất không phải khóa APIchuyên gia insight & case thực tế

Theo những gì tôi gặp khi rà lại project của người học, thứ tự thực tế là:

  1. Ảnh và file Excel dữ liệu thật để trong project cho tiện test, rồi commit. Hay nhất là ảnh chụp căn cước và ảnh nhân viên.
  2. Số điện thoại, email nội bộ gán cứng trong mã (danh sách người nhận thông báo, số của chủ doanh nghiệp).
  3. Mật khẩu quản trị gán cứng kiểu if (mk === "Admin@2026"). Vô cùng phổ biến khi làm nhanh — và vì nằm trong mã, đổi trong cơ sở dữ liệu cũng không có tác dụng.
  4. Khóa API.

Nghĩa là: lớp phòng vệ không chỉ là .gitignore cho .env. Nó là thói quen không để dữ liệu thật trong thư mục project. Tạo một thư mục C:\NVAI\du-lieu-that\ nằm ngoài mọi repo, và test bằng dữ liệu mẫu.

Đã rò rỉ rồi thì làm gì — theo đúng thứ tự

  1. Thu hồi khóa ở nơi phát hành, ngay bây giờ. Cloudflare → API Tokens → Roll/Delete. Anthropic → Console → Delete key. Đây là bước duy nhất thật sự chặn thiệt hại.
  2. Phát hành khóa mới và nạp lại vào Secrets.
  3. Xem có bị dùng chưa. Cloudflare: Audit Log. Anthropic Console: tab Usage — có mức dùng bất thường là đã bị dùng.
  4. Mới tới việc dọn lịch sử Git (nếu repo công khai).

Lưu ý tâm lý: ai cũng muốn làm bước 4 trước vì nó cho cảm giác "xóa được dấu vết". Nhưng bot đã lấy khóa thì việc bạn xóa khỏi lịch sử không lấy lại được gì. Thu hồi trước.

Ranh giới với AI — nói thẳng

Trợ lý AI giúp bạn rất nhiều việc, nhưng có một đường không bước qua:

  • Không đưa mật khẩu, khóa API, mã OTP cho AI, kể cả khi nó đang giúp bạn cấu hình và việc đó sẽ nhanh hơn.
  • Không để AI nhập đăng nhập hộ bạn. Cách làm đúng: nó mở sẵn trang đăng nhập, phần gõ là của bạn.
  • Khi dán log hoặc mã cho AI, xóa khóa đi trước. Thay bằng sk-ant-XXXX.

Lý do không phải là "AI xấu". Lý do là: nội dung hội thoại có thể được lưu lại, và một khóa đã ra khỏi tầm kiểm soát của bạn thì không rút lại được. Một trợ lý làm việc đúng mực sẽ tự từ chối việc này — nếu nó xin mật khẩu của bạn, đó là tín hiệu nên dừng lại.

Bắt AI tự rà project tìm bí mật lộchuyên gia thực thi

Chạy định kỳ, nhất là trước khi chuyển repo từ riêng tư sang công khai:

Rà toàn bộ project này và liệt kê mọi chỗ có thể là bí mật bị để lộ:
- khóa API, token, mật khẩu gán cứng trong mã
- số điện thoại, email, họ tên người thật
- file dữ liệu thật (.xlsx, .csv, .db, ảnh người)
- bí mật nằm trong [vars] của wrangler.toml

Với mỗi chỗ: nói file, dòng, và loại rủi ro. Chỉ đọc, đừng sửa gì.
Cũng kiểm giúp tôi lịch sử Git: git log --all --name-only | grep -Ei
"\.env|\.dev\.vars|\.xlsx|\.csv|\.pem"

Chạy lệnh này trên các project cũ của bạn — rất hay có kết quả, và lần đầu thường làm người ta lạnh sống lưng.

Tôi từng nghĩ repo riêng tư là an toàn tuyệt đốingười dùng bình thường góp ý

Nên tôi cứ để mật khẩu admin trong mã. Lý lẽ của tôi: "có mình xem thôi".

Hai chuyện làm tôi đổi ý. Một: tôi mời một bạn vào repo để nhờ xem hộ một lỗi — và bạn ấy thấy hết. Hai: sáu tháng sau tôi muốn mở mã đó ra làm ví dụ cho người khác, và không mở được, vì phải đi dọn mật khẩu rải trong lịch sử của 200 commit.

Bài học của tôi: làm đúng từ đầu không tốn thêm thời gian. wrangler secret put mất 20 giây. Dọn hậu quả mất một buổi.

Chốt review bài nàychuyên gia review
  • Đủ: bốn chỗ giữ bí mật, phân biệt vars/secret, danh sách không commit, quy trình xử lý rò rỉ theo thứ tự đúng, ranh giới với AI, đề rà tự động.
  • Chưa nói: quản lý bí mật cho nhóm nhiều người, luân chuyển khóa tự động. Chưa cần ở mức này.
  • Rủi ro còn lại: bài này không chống được rò rỉ qua ảnh chụp màn hình — rất hay gặp khi bạn gửi màn hình dashboard cho người khác để hỏi. Trước khi chụp, che phần token và Account ID.
Bài tập chốt
  1. Chạy đề rà tự động ở trên cho tất cả project bạn từng làm, kể cả project bỏ dở.
  2. Với mỗi khóa tìm thấy: thu hồi, phát hành mới, nạp bằng wrangler secret put hoặc gh secret set.
  3. Tạo thư mục C:\NVAI\du-lieu-that\ ngoài mọi repo, chuyển hết file dữ liệu thật ra đó.
  4. Kiểm lại bằng git check-ignore -v .dev.vars.

Việc 1 là việc nên làm hôm nay, không để sang tuần. Khóa đã lộ thì mỗi ngày là một ngày rủi ro.