Quay lại blog

Bắt đầuHướng dẫn

Lưu trữ API key an toàn: biến môi trường, .gitignore, sửa khi lộ

Giữ khóa CheapTokens của bạn ngoài mã và git: đặt biến môi trường, thêm .env vào .gitignore, và biết phải làm gì nếu khóa bị lộ.

Bởi CheapTokens TeamĐã xuất bản 6 phút đọc

Terminal với lệnh export biến môi trường và dòng .gitignore cho một API key
Trên trang này
  1. Vì sao khóa không thuộc về mã của bạn
  2. Bước 1: đưa khóa vào biến môi trường
  3. Bước 2: dùng tệp .env mà không commit nó
  4. Nếu khóa bị lộ: làm gì, theo thứ tự
  5. Tự kiểm tra

Giữ khóa trong biến môi trường, không phải trong mã của bạn, và giữ mọi tệp .env ngoài git bằng một dòng trong .gitignore. Nếu khóa đã lỡ lọt ra nơi công khai, hãy xử lý khóa trước rồi mới dọn dẹp sau: việc xóa lịch sử git trong khi khóa vẫn còn nằm trong mã và công cụ của bạn chẳng sửa được gì.

Đó là toàn bộ ý tưởng. Hướng dẫn này là phiên bản thực hành (phần cơ bản nằm trong What is an API key): ba lệnh, một yêu cầu chạy được, và một kế hoạch ngắn cho ngày xấu trời.

Vì sao khóa không thuộc về mã của bạn#

Một API key là mật khẩu tiêu tiền của bạn. Bất kỳ ai giữ nó đều có thể gửi yêu cầu trên số dư của bạn, và dịch vụ không thể phân biệt họ với bạn.

Cách nó thường hỏng thì rất nhàm chán. Bạn dán khóa vào một script để chạy được yêu cầu đầu tiên, script chạy được, bạn git push, và kho lưu trữ là công khai. Hoặc bạn gửi đồng nghiệp tệp cấu hình của mình. Hoặc bạn chụp màn hình một lỗi có khóa lộ ra ở góc. Kết quả lần nào cũng như nhau.

GitHub biết rõ kiểu này. Tính năng quét bí mật của nó (GitHub docs, kiểm tra ngày 29 tháng 10 năm 2026) duyệt toàn bộ lịch sử Git trên mọi nhánh để tìm thông tin xác thực bị mã hóa cứng, và cả trong issues, pull request, discussions, wiki và secret gist, rồi đưa ra cảnh báo khi tìm thấy. Nghĩa là xóa dòng đó trong commit tiếp theo chẳng thay đổi gì: commit cũ vẫn còn nó.

Đây là cùng một script trước và sau.

So sánh

Cùng script, khóa đã được đưa ra khỏi mã

Khóa trong mã

python
from openai import OpenAI

client = OpenAI(
    base_url="https://api.cheaptokens.dev/v1",
    api_key="<your-key>",  # pasted here: ends up in git
)

Khóa từ môi trường

python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.cheaptokens.dev/v1",
    api_key=os.environ["CHEAPTOKENS_API_KEY"],
)

Phiên bản thứ hai có thể đưa lên GitHub, vào chat hay buổi review mã nguyên như vậy. Khóa nằm trên máy bạn, ngoài tệp.

Bước 1: đưa khóa vào biến môi trường#

Biến môi trường là một giá trị có tên mà terminal của bạn trao cho mọi chương trình nó khởi chạy. Script hỏi CHEAPTOKENS_API_KEY theo tên và không bao giờ thấy nó đến từ đâu.

Trên macOS và Linux:

bash
export CHEAPTOKENS_API_KEY="<your-key>"

Trên Windows PowerShell:

powershell
setx CHEAPTOKENS_API_KEY "<your-key>"

Hai chi tiết hay làm người ta vấp. export chỉ kéo dài trong cửa sổ terminal đó, nên để giữ lại, hãy thêm dòng vào profile shell của bạn (~/.zshrc hoặc ~/.bashrc). Và setx không thay đổi cửa sổ bạn vừa gõ: hãy mở terminal mới trước khi thử.

Giờ là một yêu cầu đầy đủ. Nó dùng endpoint tương thích OpenAI, https://api.cheaptokens.dev/v1, và DeepSeek-V4-Flash với id đầy đủ (deepseek-ai/DeepSeek-V4-Flash-0731; lấy id từ CheapTokens docs, vì tên khác nhau giữa các nhà cung cấp):

python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.cheaptokens.dev/v1",
    api_key=os.environ["CHEAPTOKENS_API_KEY"],
)

resp = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-V4-Flash-0731",
    messages=[{"role": "user", "content": "Say hi in five words."}],
)
print(resp.choices[0].message.content)
print(resp.usage)

Một lời chào ngắn là yêu cầu khoảng 20 token vào và 20 token ra, mà theo giá hiện tại là $0.0000023 (danh sách đầy đủ ở trang giá). Nếu bạn chưa gửi yêu cầu đầu tiên, Your first API request with CheapTokens hướng dẫn từ con số không.

Câu trả lời của mô hình trả về trong choices[0].message.content, và usage cho thấy số token nó đếm được. Khóa không bao giờ xuất hiện trong tệp.

Terminal hiển thị các lệnh .env và .gitignore
Ba lệnh giữ khóa ngoài git

Bước 2: dùng tệp .env mà không commit nó#

Gõ export trong mỗi cửa sổ mới thì mệt. Tệp .env giữ giá trị ở một chỗ, ngay cạnh dự án:

text
CHEAPTOKENS_API_KEY=<your-key>

Python đọc nó bằng python-dotenv (pip install python-dotenv):

python
from dotenv import load_dotenv
load_dotenv()  # fills os.environ from .env

Tệp chỉ an toàn nếu git không bao giờ thấy nó. Thêm nó vào .gitignore trước commit đầu tiên:

bash
echo ".env" >> .gitignore
git check-ignore -v .env

Nếu mọi thứ đúng, lệnh thứ hai in ra đại loại .gitignore:1:.env .env: git cho bạn biết quy tắc nào đang bỏ qua tệp. Nếu nó không in gì, quy tắc chưa hoạt động. Trên Windows, tạo .gitignore trong trình soạn thảo với một dòng .env, hoặc dùng Add-Content .gitignore .env: >> của PowerShell có thể ghi UTF-16, mà git có thể bỏ qua.

Một cái bẫy: .gitignore chỉ ảnh hưởng tới các tệp git chưa theo dõi. Nếu .env đã từng được commit, hãy chạy git rm --cached .env để git ngừng theo dõi nó, và coi khóa bên trong là đã lộ (xem thêm bên dưới). Một thói quen gọn gàng là commit một .env.example với tên biến và giá trị giữ chỗ thay vì giá trị thật, để đồng đội biết cần đặt gì.

Nếu khóa bị lộ: làm gì, theo thứ tự#

Có thể khóa đã lên một repo công khai, có thể nó nằm trong ảnh chụp màn hình, có thể bạn đã dán cả tệp cấu hình vào một thread diễn đàn. Thứ tự quan trọng hơn tốc độ của bất kỳ bước đơn lẻ nào.

Hướng dẫn của chính GitHub (cùng trang, kiểm tra ngày 29 tháng 10 năm 2026) là xoay vòng thông tin xác thực ngay lập tức; viết lại lịch sử Git là tùy chọn và thường không cần thiết khi thông tin xác thực đã bị thu hồi. Người ta hay làm ngược lại: dành một giờ xóa lịch sử trong khi khóa vẫn còn hiệu lực. Đừng làm vậy.

Chọn trường hợp của bạn

Chuyện gì đã xảy ra với khóa của bạn? Chọn trường hợp gần nhất

Khóa nằm trong một commit giờ đã công khai

Trước tiên hãy gỡ khóa khỏi mã, chuyển sang biến môi trường, thêm .env vào .gitignore, và xem số dư của bạn cho những yêu cầu bạn không gửi. Dọn lịch sử là việc nên làm sau đó, không phải phần khẩn cấp.

Khóa nằm trong ảnh chụp màn hình hoặc tệp được chia sẻ

Cùng thứ tự: ngừng dùng khóa đó trong công cụ của bạn và chuyển sang biến môi trường, rồi xóa bài đăng hoặc tệp nếu có thể. Một ảnh chụp màn hình đã xóa có thể đã bị sao chép, nên đừng chỉ trông cậy vào việc xóa.

Cùng một khóa được dùng trong nhiều công cụ

Hãy đi qua mọi nơi từng chứa khóa: profile shell của bạn, các tệp .env, công cụ trình soạn thảo và terminal, và trỏ từng cái vào biến môi trường, để chỉ còn một chỗ để thay đổi. Nếu một công cụ không đọc được biến, hướng dẫn khắc phục sự cố 401/404 cho thấy lỗi trông như thế nào.

Ba bước sau khi lộ: gỡ khóa khỏi mã, cập nhật mọi công cụ, gửi yêu cầu thử
Gỡ khóa khỏi mã trước, rồi mọi công cụ, rồi yêu cầu thử

Sau khi dọn dẹp, hãy gửi một yêu cầu thử nhỏ, như ở Bước 1, và kiểm tra số dư. Nếu nó trả lời và số dư cùng số yêu cầu trông bình thường, việc dọn dẹp đã xong; hãy để mắt tới số dư trong vài ngày tới. Một khóa từng công khai nên được coi là đã lộ ngay cả sau khi bạn gỡ nó khỏi mã, nên hãy theo dõi số dư và số lượng yêu cầu cho những gì bạn không gửi, và đừng dùng lại khóa đó ở nơi mới. Về những nơi khóa thường trú ngụ, xem Where to plug in your own API key.

Tự kiểm tra#

Tự mình thử xemThử đi: bỏ đặt biến và chạy script. Bạn thấy gì?Hiện đáp án

Python dừng với KeyError: 'CHEAPTOKENS_API_KEY' trước khi bất kỳ yêu cầu nào rời khỏi máy bạn. Đó là kiểu hỏng tốt: script từ chối chạy khi thiếu khóa thay vì lặng lẽ dùng một khóa đã dán. Nếu bạn thấy 401 thay vào đó, biến đã được đặt nhưng khóa sai; hãy kiểm tra khóa và địa chỉ theo hướng dẫn 401/404.