Bỏ qua để đến nội dung

Bảo mật

Hợp đồng định nghĩa đúng hai lược đồ bảo mật, và cả hai đều mang cùng một bí mật:

Lược đồHeaderGhi chú
ApiKeyHeaderX-API-KeyKhuyến nghị.
BearerAuthAuthorization: BearerTương đương. Dùng nó khi một thư viện client bắt buộc phải có bearer token.

Cả hai dạng đều phân giải về cùng một thông tin xác thực. GET /v1/products là endpoint duy nhất chấp nhận một lệnh gọi không xác thực.

Không có danh sách IP được phép. Giới hạn tần suất theo IP là một mức trần chia sẻ cho mọi thứ phía sau một địa chỉ — nó chặn lạm dụng, chứ không cấp hay từ chối quyền truy cập. Hãy coi khóa là toàn bộ ranh giới thẩm quyền cho tài khoản của bạn.

Một khóa API Zelnum gồm ck_ theo sau là 48 ký tự: tổng cộng 51. Bất cứ thứ gì ngắn hơn đều không phải là khóa, đây là một phép kiểm tra hữu ích khi trình quản lý bí mật làm hỏng một giá trị.

NênKhông nên
Giữ nó trong trình quản lý bí mật hoặc một biến môi trườngĐặt nó trong một repository, một tệp cấu hình mà người dùng đọc được, hoặc một log CI
Gửi nó từ máy chủ của bạnĐặt nó trong JavaScript chạy trên trình duyệt, một gói ứng dụng di động, hoặc bất kỳ client công khai nào
Đọc api_key_id khi bạn cần xác định khóaDán chính khóa đó vào một yêu cầu hỗ trợ
Che khóa trong logGhi log toàn bộ header của request

Một khóa nằm trong gói front-end không phải là bí mật. Nếu một tích hợp cần gọi API từ trình duyệt, trình duyệt nên gọi máy chủ của chính bạn và máy chủ của bạn nên giữ khóa — mức trần theo IP áp cho lưu lượng trông như chưa xác thực sẽ không cứu được bạn.

Cơ sở dữ liệu lưu một chuỗi băm SHA-256 và một tiền tố hiển thị 9 ký tự, không bao giờ lưu chính giá trị, nên một bản dump bị rò rỉ không trao cho ai một token dùng được. Mặt trái là không endpoint nào có thể trả về khóa của bạn: nếu làm mất nó, bạn phải xoay vòng.

Terminal window
curl -X GET "https://api.zelnum.com/api/v1/api-key" \
-H "X-API-Key: YOUR_KEY_HERE"

Phản hồi mang api_key_id, masked_key, last_used và created_at — cho khóa đang hoạt động được phát hành gần đây nhất trên tài khoản. Endpoint chỉ báo cáo một khóa, nên hãy đọc nó như “khóa tôi đang dùng ngay lúc này”, chứ không phải như một bản kiểm kê. Để xem mọi khóa, hãy dùng Bảng điều khiển.

last_used là cách nhanh nhất để xác nhận một lần xoay vòng đã có hiệu lực, với một lưu ý: nó chỉ được ghi nhiều nhất một lần mỗi năm phút cho mỗi khóa, nên một khóa đang được dùng nhiều vẫn có thể hiển thị như chưa từng được dùng trong tối đa năm phút sau khi bạn chuyển sang nó. Đừng kết luận một lần triển khai bị hỏng chỉ từ một last_used cũ.

Một tài khoản có thể giữ nhiều khóa hoạt động cùng lúc, và Bảng điều khiển quản lý chúng riêng lẻ:

Thao tác trong Bảng điều khiểnHiệu lực
TạoThêm một khóa. Mọi khóa hiện có vẫn hoạt động.
Tạo lạiVô hiệu hóa khóa đó và phát hành một khóa thay thế cùng tên. Khóa gốc ngừng hoạt động ngay lập tức.
XóaLoại bỏ hẳn một khóa.

Điều đó cho bạn hai kiểu xoay vòng, và lựa chọn phụ thuộc vào việc bạn có chịu được một khoảng chồng lấn hay không.

Tạo một khóa thứ hai — kiểu xoay vòng theo giai đoạn, và là kiểu nên ưu tiên:

  1. Tạo khóa mới trong Bảng điều khiển. Không có gì khác thay đổi; khóa cũ vẫn xác thực được.
  2. Chuẩn bị sẵn giá trị mới ở mọi nơi cần đến — máy chủ ứng dụng, worker, cron job, script theo lịch — mà chưa kích hoạt nó.
  3. Chuyển đổi các lần triển khai. Xác minh bằng GET /v1/api-key cho đến khi nó báo api_key_id mới, có tính đến độ chi tiết năm phút của last_used.
  4. Xóa khóa cũ khi không còn gì gọi bằng nó. Đây là bước thực sự loại bỏ thông tin xác thực — một lần xoay vòng chưa kết thúc cho đến khi bước này được làm xong.

Tạo lại tại chỗ — khi giá trị cũ buộc phải chết ngay:

Dùng cách này khi một khóa đã bị lộ và việc nó tiếp tục có hiệu lực là một rủi ro.

  1. Chấp nhận khoảng trống. Khóa cũ ngừng hoạt động ngay khi bạn tạo lại, nên mọi thành phần còn giữ nó đều trả về 401 unauthorized cho đến khi được triển khai lại. Không có chồng lấn, theo thiết kế.
  2. Tạo lại trong Bảng điều khiển và sao chép ngay giá trị dạng rõ ra khỏi banner — nó chỉ hiển thị ở đó và không bao giờ ở nơi nào khác nữa.
  3. Triển khai giá trị mới, rồi xác nhận không còn gì ghi log 401 nữa.

Mọi endpoint đều dùng HTTPS. Không có cổng lắng nghe dạng rõ, và không endpoint nào chấp nhận hạ cấp, nên không có cấu hình nào khiến một khóa truyền đi mà không được mã hóa.

Nếu bạn dựng một proxy hoặc gateway trước API, hãy kết thúc TLS ở biên và chuyển tiếp header X-API-Key — đừng viết lại nó, và đừng thêm nó vào log request đến.

Đầu vào của API là số điện thoại và địa chỉ email — dữ liệu cá nhân ở hầu hết các khu vực pháp lý. Hai hệ quả:

  • Chỉ gửi những gì bạn cần. Một lần kiểm tra chỉ cần định danh và không cần gì khác. Đừng thêm user id, một tham chiếu nội bộ, hay metadata dạng văn bản tự do vào body request: nó không được lưu như một trường, nó chỉ làm tăng mức phơi bày log của chính bạn.
  • Nắm rõ các khoảng thời gian lưu giữ. Log thời gian thực và kết quả phát lại idempotency được lưu 30 ngày theo mặc định, còn tệp kết quả hàng loạt là 7 ngày (result_retention_days). Sau các khoảng đó, bản ghi sẽ biến mất, nên hãy xuất bất cứ thứ gì bạn buộc phải giữ.

Hãy coi số điện thoại là thông tin nhạy cảm trong hệ thống của bạn nữa. Một kết quả phát hiện cho người quan sát biết một người cụ thể có đăng ký trên một nền tảng cụ thể hay không, và cặp định danh cùng kết luận tiết lộ nhiều hơn từng nửa riêng lẻ.

Đây vừa là một thuộc tính bảo mật vừa là một thuộc tính thanh toán: Idempotency-Key khiến việc thử lại an toàn, nên một lỗi mạng hay một người vận hành sốt ruột không thể biến một khoản thu thành hai. Không bao giờ tạo một khóa mới để thử lại một request mà bạn không quan sát được kết quả — xem Idempotency & thử lại.

  • Trạng thái & hỗ trợ — cần kèm gì khi bạn báo cáo lên hỗ trợ, mà không làm lộ khóa
  • Mã lỗi — unauthorized và account_banned trong ngữ cảnh