# Bảo mật

> **TL;DR** — API key chỉ nằm trên server của bạn. Thiết bị người xem không đáng tin: nó chỉ bao giờ giữ một vé cho một tập trên chính thiết bị đó, trong 30 phút. Thu hồi key ngay khi bạn nghĩ nó bị lộ, rồi báo cho Wandura. Không bao giờ đặt key, vé hay link đã ký vào app, code front-end, log, analytics, crash report hay URL. `viewer_ref` là một id opaque đã hash, Wandura giữ trong 90 ngày.

## Ranh giới tin cậy
```mermaid
flowchart LR
  D["Viewer device<br/>untrusted<br/>Player SDK, one ticket"] -->|"your session + device values"| B["Your backend<br/>trusted<br/>API keys, paywall, per-viewer limits"]
  B -->|"Bearer API key, TLS 1.2+"| W["Wandura Delivery API<br/>checks key, licence<br/>signs the ticket"]
  W -->|"ticket for one episode, one device"| B
  B -->|"ticket"| D
  D -->|"ticket"| S["Wandura streaming<br/>encrypted stream + keys"]
```

| Vùng | Giữ gì | Không bao giờ được giữ |
|---|---|---|
| Thiết bị người xem | Mỗi tập một vé, trong bộ nhớ; file giấy phép Player SDK | API key |
| Backend của bạn | API key, paywall, người xem của bạn | — |
| Wandura | Giấy phép của bạn, phim, sổ ghi vé | Danh tính người xem của bạn |

**Endpoint xin vé của bạn là cửa gác.** Wandura kiểm tra giấy phép của bạn, không kiểm tra người xem của bạn. Giá trị thiết bị đến từ một client bạn không kiểm soát. Vì vậy endpoint của bạn phải:

- yêu cầu phiên người xem đã đăng nhập (hoặc cơ chế xác thực thiết bị của riêng bạn) trước khi xin Wandura vé;
- áp paywall của bạn trước mỗi request xin vé;
- giới hạn số vé theo người xem và theo thiết bị (ví dụ 10 vé mỗi phút) và báo động khi người xem mở nhiều phim trong thời gian ngắn;
- coi `union_info` và `drm_kek` là đầu vào không đáng tin: chỉ chuyển tiếp, không bao giờ dùng vào việc gì khác.

Rate limit của Wandura tính theo **tổ chức**: một client lạm dụng app của bạn có thể làm cạn hạn mức của mọi người xem. Xem [Rate limit](https://docs.wandura.ai/vi/developers/concepts/rate-limits).

## Key
### Scope và quyền tối thiểu
Mỗi hệ thống và mỗi môi trường một key, chỉ với các scope hệ thống đó cần. Scope của từng endpoint nằm ở [Xác thực](https://docs.wandura.ai/vi/developers/authentication#scopes). Job đồng bộ catalog không bao giờ cần `playback`; job marketing chỉ cần `creatives:export`.

### Production và thử nghiệm
Không có host staging riêng: mọi key đều gọi `https://www.wandura.ai`. Thứ tách lưu lượng thử nghiệm ra là **tổ chức**.

Mỗi đối tác có một **tổ chức thử nghiệm** bên cạnh tổ chức thật. Key của tổ chức này gọi cùng URL production, chạy y như key thật, nhưng chỉ với phim mẫu, và lượt phát không bao giờ được tính là lượt xem, usage hay doanh thu. Nó còn nhận header `Wandura-Simulate` để tạo lỗi khi cần; key production bỏ qua hoàn toàn header này. Xem [Testing](https://docs.wandura.ai/vi/developers/guides/testing).

Không bao giờ dùng key production trong môi trường thử nghiệm, và ngược lại.

### Lưu trữ
- Giữ key trong secrets manager, chỉ mở cho đúng service cần nó, dưới tên `WANDURA_API_KEY`.
- Không bao giờ commit key. Thêm mẫu `wnd_live_[A-Za-z0-9_-]{32}` vào secret scanner và pre-commit hook của bạn.
- Tìm `wnd_live_` trong mọi bản build app trước khi phát hành: không được có kết quả nào.

### Vòng đời key
| Thao tác | Ai | Điều xảy ra |
|---|---|---|
| Tạo | Admin hoặc Developer, trên **Developers** | Key đầy đủ chỉ hiện một lần. Key mới được ghim vào phiên bản API theo ngày **mới nhất**. |
| Xoay | Admin hoặc Developer | Thay secret, giữ nguyên nhãn, scope và **phiên bản đang ghim**. Secret cũ bị từ chối trong khoảng **1 giây** trên mọi server của Wandura (luôn trong vòng 30 giây), không có thời gian chồng lấn. |
| Thu hồi | Admin hoặc Developer | Không quay lại được. Request mới dùng key bị từ chối trong khoảng **1 giây** (luôn trong vòng 30 giây). |
| Vé đã cấp | — | Vẫn phát tiếp cho tới khi hết hạn (≤ 30 phút). Không thu hồi được. |

**Xoay key không gián đoạn:** tạo key thứ hai cùng scope, triển khai nó, kiểm tra lưu lượng đã chuyển sang (**Last used** của key cũ thôi thay đổi), rồi thu hồi key cũ. Key mới được ghim vào phiên bản theo ngày mới nhất: nếu key cũ ghim vào một phiên bản cũ hơn, hãy gửi `Wandura-Version: <your date>` kèm key mới, hoặc đọc `api.pinned_version` từ `GET /config` bằng cả hai key trước khi chuyển. Xem [Chuyển phiên bản](https://docs.wandura.ai/vi/developers/guides/migrating-versions).

Wandura theo dõi các playback key mới tạo hoặc vừa xoay, và các tổ chức chạm ngưỡng playback. Bạn vẫn là người chịu trách nhiệm về key của mình: hãy theo dõi **Last used** và **API usage**, và báo Wandura ngay nếu nghi key bị lộ.

Mọi lần tạo, xoay và thu hồi key đều được ghi vào audit log của Wandura, kèm tổ chức của bạn, thành viên đã thực hiện và tiền tố key.

## Nếu key bị lộ
1. **Thu hồi** trên **Developers** (bất kỳ Admin hay Developer nào). Request mới ngừng trong khoảng một giây.
2. **Triển khai key thay thế** cùng scope. Chú ý phiên bản đang ghim (ở trên).
3. **Báo cho Wandura** trong kênh Discord Wandura của team bạn: tiền tố key, lộ khi nào và ở đâu. Wandura có thể liệt kê các vé đã cấp bằng key đó (lưu 90 ngày) và, nếu các vé đã cấp phải dừng trước khi hết hạn, tạm ngưng các phim bị ảnh hưởng cho tổ chức của bạn.
4. **Kiểm tra** **Developers → API usage** để tìm lời gọi không phải do bạn.
5. **Bịt đường lộ**: repository, file build của app, log, crash report, output của CI. Thêm mẫu cho secret scanner.

Gọi `http://` thay vì `https://` sẽ gửi key không mã hoá trước khi bị chuyển hướng: hãy coi key đó là đã lộ.

## Vé và link đã ký
| Giá trị | Luật |
|---|---|
| `play_auth_token` | Bearer secret cho một tập trên một thiết bị, hiệu lực ≤ 30 phút. Giữ trong bộ nhớ cho lượt phát hiện tại. Không bao giờ ghi ra đĩa, log, analytics hay crash report. |
| `manifest_url` | Bearer link: ai có nó đều tải được stream cho tới `expires_at` (≤ 15 phút). Cùng luật như token. |
| Link video mở | Ai có link đều phát hoặc tải được file cho tới khi hết hạn (1 giờ). Đừng công khai, đừng lưu trong app. |
| URL phụ đề | Công khai và sống lâu. Cache thoải mái; đừng công khai danh sách các URL này. |

Token hay link bị lộ sẽ tự hết hạn; hãy chặn đường đã làm lộ nó.

## Dữ liệu người xem và thiết bị
- **`viewer_ref`** là tuỳ chọn, opaque, tối đa 256 ký tự. Wandura lưu nó cùng mỗi vé trong **90 ngày** để tra cứu khi hỗ trợ, sau đó chỉ giữ số đếm theo tháng. Không bao giờ đặt email, số điện thoại hay tên vào đây. Hãy dùng hash có khoá: `HMAC(secret, user_id)` cộng hash của install id, để giá trị vô nghĩa bên ngoài hệ thống của bạn và ổn định theo người xem và thiết bị. Các [ví dụ](https://docs.wandura.ai/vi/developers/guides/playback-flow#code) làm đúng như vậy.
- **`union_info`** là định danh thiết bị lâu dài do Player SDK tạo ra: phía bạn, đây là dữ liệu cá nhân. Wandura chỉ dùng giá trị thiết bị để gắn vé và không lưu chúng. Đừng ghi log giá trị thô; hãy hash nếu cần để debug.

## Không bao giờ đặt secret ở đây
| Giá trị | App / JS front-end | Log server, APM, proxy | Analytics | Crash report | URL | Chat hỗ trợ |
|---|---|---|---|---|---|---|
| API key | **không bao giờ** | **không bao giờ** (che `Authorization`) | **không bao giờ** | **không bao giờ** | **không bao giờ** | chỉ tiền tố |
| `play_auth_token`, `manifest_url` | chỉ trong bộ nhớ, lượt phát hiện tại | **không bao giờ** | **không bao giờ** | **không bao giờ** | **không bao giờ** | **không bao giờ** |
| `union_info`, `drm_kek` | được tạo ở đó | chỉ bản hash | **không bao giờ** | tránh | **không bao giờ** | nếu được hỏi |
| `viewer_ref` | — | được | chỉ dạng bí danh | được | tránh | được |

Hàm ghi log an toàn trong các ví dụ tự bỏ các trường này cho bạn: [Observability](https://docs.wandura.ai/vi/developers/production/observability#never-log).

## Đường truyền
- Luôn dùng `https://www.wandura.ai`. Chỉ TLS 1.2 hoặc 1.3.
- Không dùng `wandura.ai` thiếu `www`: nó chuyển hướng, và một số client làm mất body của `POST` khi bị chuyển hướng.
- API không dùng cookie để xác thực và không gửi header CORS: lời gọi từ trình duyệt sẽ thất bại, đó là cố ý.
- Không bao giờ đặt key trong query string. API chỉ đọc header `Authorization`.

## Liên quan
- [Xác thực](https://docs.wandura.ai/vi/developers/authentication): cách gửi key, scope.
- [Checklist trước khi go-live](https://docs.wandura.ai/vi/developers/production/go-live): các mục bảo mật cần đánh dấu trước khi phát hành.
- [Hành vi chuẩn của API](https://docs.wandura.ai/vi/developers/reference/behaviour#freshness): mọi mốc thời gian trên một trang.
