Mã hóa thông tin nhạy cảm của bạn trước khi lưu trữ dùng SOPS và AGE

Tìm hiểu cách mã hóa các file thông tin nhạy cảm (secrets) an toàn trước khi đẩy lên Git repository bằng bộ đôi công cụ SOPS và AGE.

Mã hóa thông tin nhạy cảm của bạn trước khi lưu trữ dùng SOPS và AGE

Việc đưa trực tiếp các file chứa thông tin nhạy cảm (secrets) như mật khẩu, access token hay khóa API lên Git Repository có thể làm rò rỉ dữ liệu cực kỳ nguy hiểm. Nhiều người cho rằng lưu trữ trên các Git Repo riêng tư (Private Repo) là an toàn, nhưng thực tế điều đó vẫn mang lại rủi ro rất lớn.

Dù bạn sử dụng Repo công khai hay riêng tư, một quy tắc bất di bất dịch là hãy mã hóa thông tin nhạy cảm trước khi commit.

Bài viết này sẽ hướng dẫn bạn cách sử dụng bộ đôi công cụ mạnh mẽ Mozilla SOPSAGE để mã hóa an toàn các file cấu hình.

SOPS và AGE là gì?

  • Mozilla SOPS (Secret Operations): Là một trình chỉnh sửa file được mã hóa, hỗ trợ nhiều định dạng file phổ biến như YAML, JSON, ENV, INI và BINARY. Nó có thể kết hợp với các dịch vụ quản lý khóa như AWS KMS, GCP KMS, Azure Key Vault, PGP và đặc biệt là AGE.
  • AGE: Là một công cụ, định dạng và thư viện mã hóa tệp đơn giản, hiện đại và bảo mật được viết bằng ngôn ngữ Go. AGE giúp bạn mã hóa và giải mã các file, đảm bảo an toàn tuyệt đối khi đưa lên các Git repo.

1. Cài đặt các công cụ

Cài đặt SOPS

Bạn có thể cài đặt SOPS thông qua hướng dẫn chính thức trên Github.

Sau khi cài đặt xong, hãy kiểm tra phiên bản:

sops -v

Kết quả dự kiến:

sops 3.7.3 (latest)

Cài đặt AGE

Tương tự, hãy làm theo hướng dẫn cài đặt của AGE.

Kiểm tra xem bạn đã cài đặt thành công chưa:

age -version

Kết quả dự kiến: v1.0.0

Tiếp theo kiểm tra age-keygen:

age-keygen -version

Kết quả dự kiến: v1.0.0

2. Cấu hình Key (Khóa mã hóa)

Bây giờ AGE đã được cài đặt, chúng ta cần tạo một cặp khóa Public Key và Private Key:

age-keygen -o key.txt

Bạn sẽ thấy cảnh báo sau (báo rằng file đang có quyền đọc công khai, ta sẽ xử lý sau):

age-keygen: warning: writing secret key to a world-readable file
Public key: age1epzmwwzw8n09slh0c7z0z52x43nnga7lkksx3qrh07tqz5v7lcys45428t

Hãy xem nội dung file key.txt vừa tạo:

cat key.txt

Nội dung file sẽ tương tự như sau:

# created: 2026-06-07T21:55:47-05:00
# public key: age1epzmwwzw8n09slh0c7z0z52x43nnga7lkksx3qrh07tqz5v7lcys45428t
AGE-SECRET-KEY-1HJCRJVK7EE3A5N8CRP8YSDUGZKNW90Y5UR2RGYAS8L279LFP6LCQU5ADNR

⚠️ Cảnh báo: Đây là thông tin cực kỳ bảo mật (Secret Key). Hãy giữ nó ở nơi an toàn tuyệt đối và KHÔNG BAO GIỜ được commit lên Git.

Lưu trữ khóa và cấu hình biến môi trường:

Ta sẽ di chuyển file khóa này vào một thư mục an toàn và cấu hình cho Terminal biết vị trí của nó.

mkdir ~/.sops
mv ./key.txt ~/.sops

Khai báo biến môi trường vào file cấu hình shell của bạn:

nano ~/.zshrc 
# hoặc nano ~/.bashrc

Thêm dòng sau vào cuối file:

export SOPS_AGE_KEY_FILE=$HOME/.sops/key.txt

Cập nhật lại shell:

source ~/.zshrc 
# hoặc source ~/.bashrc

3. Bắt đầu quá trình mã hóa với các loại file

Có nhiều cách để sử dụng SOPS. Bạn có thể mở trình chỉnh sửa (editor) để sửa trực tiếp file đã mã hóa, hoặc mã hóa đè lên file hiện tại (in-place). Dưới đây chúng ta sẽ làm theo cách mã hóa in-place.

3.1. File YAML (Ví dụ Kubernetes Secrets)

Ví dụ với file secret.yaml:

---
apiVersion: v1
kind: Secret
metadata:
    name: mysql-secret
    namespace: default
stringData:
    MYSQL_USER: root
    MYSQL_PASSWORD: MySecret-Password!!!!

Cách mã hóa (Encrypt):

sops --encrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") --encrypted-regex '^(data|stringData)$' --in-place ./secret.yaml

Cách giải mã (Decrypt):

sops --decrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") --encrypted-regex '^(data|stringData)$' --in-place ./secret.yaml

Đối với Kubernetes: Bạn có thể giải mã và truyền trực tiếp thông tin vào kubectl mà không cần ghi nội dung chưa mã hóa xuống ổ cứng:

# Mã hóa file
sops --encrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") --encrypted-regex '^(data|stringData)$' --in-place ./secret.yaml

# Giải mã on-the-fly và apply vào cụm Kubernetes
sops --decrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") --encrypted-regex '^(data|stringData)$' ./secret.yaml | kubectl apply -f -

Bạn có thể kiểm tra secret đã được tạo trên cụm K8s chưa bằng lệnh:

kubectl describe secrets mysql-secret-test
kubectl get secret mysql-secret-test -o jsonpath='{.data}'
kubectl get secret mysql-secret-test -o jsonpath='{.data.MYSQL_PASSWORD}' | base64 --decode

3.2. File .ENV

Tạo file secret.env:

MYSQL_USER=superroot
MYSQL_PASSWORD="MySecret-Password!!!!############"

Cách mã hóa (Encrypt):

sops --encrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") -i .env

Cách giải mã (Decrypt):

sops --decrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") -i .env

(Đừng quên thêm file đã giải mã, ví dụ .decrypted~secret.env vào file .gitignore của bạn)

3.3. File JSON

Tạo file secret.json:

{
    "mySqlUser": "superroot",
    "password": "MySecret-Password!!!!#######"
}

Cách mã hóa (Encrypt):

sops --encrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") -i secret.json

Cách giải mã (Decrypt):

sops --decrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") -i secret.json

3.4. File INI

Tạo file secret.ini:

[database]
user     = superroot
password = MySecret-Password!!!!1223

Cách mã hóa (Encrypt):

sops --encrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") -i secret.ini

Cách giải mã (Decrypt):

sops --decrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") -i secret.ini

3.5. File SQL thông thường (Binary hoặc Plain Text)

Tạo file secret.sql:

--- https://xkcd.com/327/
--- DO NOT USE
INSERT INTO Students VALUES ( 'Robert' );  DROP TABLE STUDENTS; --' )

Cách mã hóa (Encrypt):

sops --encrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") --in-place ./secret.sql

Cách giải mã (Decrypt):

sops --decrypt --age $(cat $SOPS_AGE_KEY_FILE |grep -oP "public key: \K(.*)") --in-place ./secret.sql

Tích hợp SOPS trên VS Code

Nếu bạn làm việc chủ yếu qua VS Code, có extension hỗ trợ SOPS rất tiện lợi. Hãy tìm kiếm trên MarketPlace tiện ích SOPS Beta (hỗ trợ cả SOPS và AGE) để cài đặt, giúp bạn dễ dàng xem file đã mã hóa một cách nhanh chóng ngay trên editor.

Lời kết

Mã hóa mọi thông tin nhạy cảm trước khi commit là bước không thể thiếu để bảo đảm an toàn hệ thống của bạn. Bằng cách sử dụng SOPS kết hợp với AGE, việc quản lý file secrets chưa bao giờ trở nên dễ dàng và an toàn đến thế.

Bình luận

Bài viết liên quan