# Xử lý dữ liệu nhạy cảm trong Odoo, phần 1: Bốn thao tác và khi nào dùng cái nào

> Trung hòa, thu nhỏ, ẩn danh hóa và làm mờ là bốn thao tác khác nhau trên một bản sao database Odoo. Mỗi thao tác trả lời câu hỏi gì, và khi nào dùng cái nào.

**Date:** 2026-06-18
**Source:** <https://trobz.com/vi/insights/handling-sensitive-data-in-odoo-approaches/>

---



Mỗi lần khôi phục một database production lên máy của lập trình viên, lên máy chủ
staging hay lên một CI runner đều là một vụ rò rỉ dữ liệu đang chờ xảy ra. Email
khách hàng thật, lương, tài khoản ngân hàng và thông tin đăng nhập API đang hoạt
động rơi vào những nơi chưa bao giờ được dự tính để chứa chúng. Những cron vốn
đang ngủ yên trên production thì thức dậy trên bản sao và bắt đầu gửi email cho
người thật.

Cách sửa không nằm ở một công cụ duy nhất. Đó là bốn thao tác khác nhau mà người
ta vẫn thường xuyên lẫn lộn: **trung hòa**, **thu nhỏ**, **ẩn danh hóa** và
**làm mờ**.
Chúng có phần chồng lấn, thường được chạy cùng nhau, nhưng trả lời những câu hỏi
khác nhau. Bài này định nghĩa từng thao tác và đưa ra một quy tắc để biết khi nào
dùng cái nào.

Đây là phần 1 của một loạt ba bài. Phần 2 điểm qua các công cụ bên ngoài (module
cộng đồng và extension của PostgreSQL). Phần 3 đi qua cách Trobz xử lý chuyện này.

---

## Bốn thao tác nhìn trong một bảng

| Thao tác | Câu hỏi nó trả lời | Tình huống điển hình |
|-----------|--------------------|-------------------|
| Trung hòa | "Bản sao này có nói chuyện ra thế giới bên ngoài không, và nó có trỏ đúng môi trường không?" | Mọi lần khôi phục không phải production |
| Thu nhỏ | "Bản sao này đã đủ nhẹ để làm việc chưa?" | Database production lớn, dùng ở máy cá nhân hoặc CI |
| Ẩn danh hóa | "Từ bản sao này có truy ngược ra một con người cụ thể không?" | Bản sao ra khỏi vòng tin cậy (debug, kiểm thử tự động, demo) |
| Làm mờ | "Có thể che giá trị bây giờ rồi khôi phục lại sau không?" | Bản sao phải quay về với giá trị thật |

Ba thao tác đầu xếp theo thứ tự dữ liệu đi xa tới đâu. Một bản sao nằm yên trên
một máy chủ staging tin cậy thì cần trung hòa. Một bản sao đi vào kiểm thử tự
động hoặc lên một máy tính không được quản lý thì cần cả ba. Làm mờ nằm ngoài thứ
tự đó: nó che giá trị theo kiểu đảo ngược được.

---

## Trung hòa

Trung hòa ngăn một bản sao database tương tác với thế giới bên ngoài: không gửi
thư đi, không thu tiền thanh toán, không gọi ra API bên ngoài, không có tác vụ
theo lịch nào bắn vào hệ thống đang chạy thật. Nó cũng lo nốt nửa còn lại của
cùng công việc đó, là điều chỉnh bản sao cho hợp với môi trường nó vừa chuyển
tới, để những gì nó còn với tới được đều thuộc về môi trường đó chứ không phải
production.

Trung hòa có hai nửa. Nửa do module điều khiển đã là một lệnh chính thức từ
Odoo 16.0:

```bash
odoo neutralize
```

Cơ chế là SQL thuần, không phải Python. `odoo neutralize` đọc danh sách module đã
cài từ `ir_module_module`, và với mỗi module có kèm một file
`data/neutralize.sql` thì chạy file đó. Không có phương thức `_neutralize()` nào
để ghi đè; một module tham gia đơn giản bằng cách thêm file đó vào. Trên các
module hiện có kèm file này, phạm vi bao gồm:

- Thư gửi đi (`base`: vô hiệu hóa `ir_mail_server`, chèn vào một máy chủ giả để
  dự phòng)
- Cron / tác vụ theo lịch (`base`: vô hiệu hóa các bản ghi `ir.cron`, trừ tác vụ
  autovacuum)
- Đồng bộ ngân hàng
- Nhà cung cấp thanh toán (theo từng module thanh toán: xóa sạch thông tin đăng
  nhập của nhà cung cấp)
- Tích hợp giao vận (`delivery`: tắt môi trường prod và các hãng vận chuyển bên
  ngoài)
- Tiêu thụ IAP (`iap`: vô hiệu hóa các token `iap_account`)
- Lập chỉ mục và hiển thị của website (`website`: xóa domain, tắt CDN, đặt
  `robots.txt` chặn mọi bot)

Vì phần SQL nằm ngay cạnh module mà nó bảo vệ, trung hòa là chỗ đúng đắn cho
phần an toàn riêng của từng module. Nếu bạn viết một module mà, chẳng hạn, đồng
bộ một token xác thực giữa website và backend Odoo theo từng công ty, module đó
nên kèm một `data/neutralize.sql` xóa hoặc làm giả token. Người viết tích hợp
biết rõ chỗ nào nguy hiểm; kiến thức đó thuộc về module, không thuộc về một
script riêng mà ai đó phải nhớ cập nhật.

### Trung hòa tự động trên Odoo.sh

Odoo.sh tự chạy trung hòa cho bạn trong hai tình huống:

1. Khi một bản dump production được khôi phục lên một nhánh staging.
2. Theo mặc định, khi một bản dump database được tải về qua giao diện Odoo.sh.

   ![Hộp thoại tải bản dump của Odoo.sh, với tùy chọn trung hòa database được bật sẵn](/images/insights/handling-sensitive-data-in-odoo-approaches/odoo-sh-download-dump.webp)

### Nửa phụ thuộc môi trường

`odoo neutralize` chạy ở đâu cũng giống nhau. Nửa còn lại phụ thuộc vào nơi bản
sao vừa đặt chân tới: nó chỉnh database sao cho chạy đúng *trong môi trường mới*,
trỏ vào cấu hình của chính môi trường đó thay vì của production.

Các bước điển hình:

- Cập nhật `web.base.url` và `report.url` sang tên miền của môi trường mới.
- Đặt lại mật khẩu admin về một giá trị đã biết.
- Trỏ catchall/alias domain của thư sang một tên miền dùng để thử nghiệm.
- Đổi các endpoint kết nối ra ngoài (CRM, thương mại điện tử, công cụ marketing)
  sang thông tin đăng nhập của chính môi trường đó.

Nhu cầu này rất cụ thể. Giả sử một dự án CRM kết nối tới một dịch vụ quản trị bên
ngoài qua API, và mỗi môi trường lẽ ra phải dùng thông tin đăng nhập riêng. Khôi
phục production lên staging mà bỏ qua bước này, thì staging giờ đây xác thực với
dịch vụ bên ngoài đó dưới danh nghĩa production.

> **Quy tắc:** Trung hòa là không thể thương lượng trên mọi database không phải
> production. Đó là sàn, không phải trần.

Điều trung hòa *không* làm: nó không gỡ bỏ dữ liệu cá nhân. Đó là việc của hai
thao tác tiếp theo.

---

## Thu nhỏ

Thu nhỏ (còn gọi là minify) xóa bớt các bản ghi mà môi trường đích không cần, để
bản sao nhẹ hơn và làm việc nhanh hơn. Một database production nặng vài gigabyte
rất khổ khi phải khôi phục đi khôi phục lại trên máy cá nhân hay trong CI; cắt
bớt nhiều năm giao dịch lịch sử, file đính kèm cũ hoặc các bảng log rời rạc có
thể giảm được cả một bậc độ lớn.

Thu nhỏ là thao tác duy nhất hoàn toàn thuộc về sự tiện dụng, không thuộc về an
toàn. Bỏ qua nó thì bạn vẫn có một bản sao đúng và an toàn — chỉ là chậm và nặng.
Vì xóa bản ghi nghĩa là phải lách qua các khóa ngoại và ràng buộc toàn vẹn tham
chiếu của Odoo, đây cũng là thao tác khó làm cho đúng nhất, và đó là lý do nó chỉ
dành cho những trường hợp mà kích thước thật sự gây đau.

> **Khuyến nghị:** Chỉ thu nhỏ khi kích thước thật sự là vấn đề. Với hầu hết các
> lần khôi phục lên staging, một bản sao nguyên cỡ sẽ đơn giản và ít rủi ro hơn
> một bản đã bị xóa dở.

---

## Ẩn danh hóa

Ẩn danh hóa gỡ bỏ hoặc thay thế dữ liệu cá nhân và dữ liệu nhạy cảm để không thể
truy ngược ra một cá nhân nào từ bản sao. Đây là thao tác có sức nặng pháp lý
đứng sau: theo GDPR và các quy định tương tự, một bản sao production đầy dữ liệu
cá nhân thật nằm trên máy của một lập trình viên là một hoạt động xử lý dữ liệu
mà nhiều khả năng bạn không biện minh được.

Ẩn danh hóa nhắm vào:

- **PII trực tiếp:** họ tên, email, số điện thoại, địa chỉ, số định danh cá nhân,
  số tài khoản ngân hàng, ngày sinh.
- **Dữ liệu kinh doanh nhạy cảm:** lương, giá vốn, biên lợi nhuận, giá bán — dữ
  liệu mang tính bảo mật ngay cả khi không phải dữ liệu cá nhân.

Mục tiêu là một database đủ thực tế để phát triển và kiểm thử, nhưng không phơi
bày ai cả nếu bị rò rỉ. Một lập trình viên đang debug lỗi bảng lương cần các
phiếu lương có cấu trúc đáng tin; họ không cần biết lương thật của ai.

Ẩn danh hóa là thao tác nhiều việc nhất vì nó phụ thuộc vào lược đồ cụ thể. Các
công cụ chung có thể che những trường hiển nhiên như `res_partner.email`, nhưng
database thật mang PII trong cả các trường tùy chỉnh, các bản sao phi chuẩn hóa,
phần thân tin nhắn trong mail message, lịch sử giá trị theo dõi và file đính kèm.
Làm cho tới nơi nghĩa là đi qua lược đồ thật, không chỉ các bảng tiêu chuẩn.

> **Quy tắc:** Nếu một bản sao sẽ dùng cho kiểm thử tự động, chia sẻ để debug,
> hay đem ra demo — tức bất kỳ đâu ngoài vòng tin cậy vốn đã có quyền truy cập
> production — thì nó phải được ẩn danh hóa. Trung hòa không thay thế được điều
> này: một database đã trung hòa vẫn chứa đủ mọi tên thật và mức lương thật.

---

## Làm mờ

Làm mờ thay các giá trị nhạy cảm bằng giá trị đã mã hóa mà một mật khẩu có thể
đưa trở lại thành bản gốc. Odoo có sẵn tính năng này từ 16.0 dưới dạng
[`odoo obfuscate`][odoo-obfuscate]:

```bash
odoo obfuscate -d {{database}} --pwd "$OBFUSCATE_PWD" \
  --fields res_partner_bank.acc_number
odoo obfuscate -d {{database}} --pwd "$OBFUSCATE_PWD" --unobfuscate \
  --fields res_partner_bank.acc_number
```

Lệnh này mã hóa giá trị ngay tại chỗ bằng `pgcrypto` của PostgreSQL. Nó làm việc
theo từng cột, không theo từng bản ghi: mọi dòng của một cột được liệt kê đều bị
mã hóa, và không có cách nào chọn ra một tập con bản ghi. Lệnh có sẵn một danh
sách cột mặc định (tên đối tác, các trường liên hệ và địa chỉ, phần thân
`mail_message`, lịch sử `mail_tracking_value`, lead của CRM). Tham số
`--fields table.column,...` hoặc một file (`--file`, mỗi dòng một `table.column`)
mở rộng danh sách đó với các cột riêng của dự án, và đúng danh sách ấy phải được
truyền lại khi gỡ làm mờ. Chỉ các cột kiểu văn bản mới đủ điều kiện, nên số tiền,
ngày tháng và file đính kèm vẫn đọc được.

Vì các giá trị đã mã hóa được ghi đè vào chính dữ liệu thật:

- Lệnh hỏi xác nhận trước khi chạy: `This will alter data in the database <db>
  and can lead to a data loss.` Cho tới khi bản sao được gỡ làm mờ, các giá trị
  gốc chỉ tồn tại dưới dạng bản mã.
- Mật khẩu được lưu trong `ir_config_parameter` (`odoo_cyph_pwd`), mã hóa bằng
  chính nó để các lần chạy sau kiểm chứng được. Hãy giữ mật khẩu cẩn thận; mất nó
  là mất trắng mọi giá trị đã làm mờ.
- Một giá trị đã mã hóa mà bị cập nhật trong lúc database đang ở trạng thái làm
  mờ (do người dùng sửa, hoặc do một trường tính toán như `complete_name` nối
  chuỗi vào) thì không còn là bản mã hợp lệ, và lần chạy `--unobfuscate` sau đó
  sẽ hỏng ở đúng chỗ ấy.

Làm mờ không phải ẩn danh hóa. Bất kỳ ai có mật khẩu đều đọc lại được dữ liệu, và
chính lời nhắc của lệnh nói rằng nó không được coi là an toàn để chuyển dữ liệu
cho bên thứ ba. Các giá trị đã mã hóa là chuỗi base64, không phải dữ liệu kiểm
thử trông thực tế. Nó hợp với một bản sao phải quay về với giá trị thật.

---

## Một quy tắc để quyết định

Hãy xuất phát từ chỗ bản sao sẽ đi tới, rồi áp dụng mọi thứ cho tới mức đó:

1. **Mọi bản sao không phải production** → trung hòa, cả hai nửa.
2. **Bản sao lớn và kích thước gây đau** → thu nhỏ thêm.
3. **Bản sao rời khỏi vòng tin cậy** (máy của lập trình viên, CI, demo, bất kỳ ai
   không có quyền truy cập production) → ẩn danh hóa thêm.

Sai lầm phổ biến nhất và nguy hiểm nhất là dừng ở bước 1 trong khi bản sao thực
ra thuộc diện bước 3, tức coi "cron đã tắt và URL đã sửa" là "database đã an
toàn". Không phải vậy. Một máy chủ staging mà cả đội với tới được, chứa dữ liệu
production nhận diện được đầy đủ, chỉ là một vụ rò rỉ có thêm vài bước.

Làm mờ không thỏa mãn bước 3. Một bản sao đã làm mờ vẫn giữ đủ mọi giá trị thật,
chỉ cách một cái mật khẩu.

---

## Những điểm chính

Xử lý dữ liệu nhạy cảm trong Odoo là bốn thao tác, không phải một. Trung hòa ngăn
bản sao với tới thế giới bên ngoài (`odoo neutralize`, thứ thuộc về chính các
module của bạn) và cấu hình lại nó cho môi trường mới. Thu nhỏ cắt bớt cho dễ
làm việc. Ẩn danh hóa lột bỏ dữ liệu cá nhân và dữ liệu nhạy cảm để một vụ rò rỉ
không làm hại ai. Làm mờ (`odoo obfuscate`) mã hóa các cột ngay tại chỗ và đảo
ngược được, miễn là mật khẩu còn giữ và các giá trị đã mã hóa không bị đụng tới.
Chúng thường được chạy cùng nhau, nhưng biết rõ cái nào là cái nào sẽ cho bạn
biết còn thiếu gì khi một bản sao chuyển sang một nơi mới.

[odoo-obfuscate]: https://github.com/odoo/odoo/blob/16.0/odoo/cli/obfuscate.py

