Quản lý Git Credentials an toàn trên Linux với Git Credential Manager và libsecret: Lưu token GitHub/GitLab tự động

Git tutorial - IT technology blog
Git tutorial - IT technology blog

Vấn đề thực tế: Nhập password/token mãi không chán à?

Sau khi GitHub bỏ xác thực bằng password từ tháng 8/2021, mình phải chuyển sang dùng Personal Access Token (PAT). Và cái cảm giác phải paste token 40 ký tự mỗi lần git push thật sự rất phiền. Đã thế, token lại expire sau 30–90 ngày, phải generate cái mới rồi cập nhật lại.

Mình đã thử qua 4 cách khác nhau trong 6 tháng deploy thực tế, từ đơn giản nhất đến cách mà mình đang dùng hiện tại. Bài này tổng hợp lại những gì mình học được.

So sánh 4 cách lưu Git Credentials trên Linux

Cách 1: git-credential-store (lưu plaintext vào file)

Git hỗ trợ sẵn, không cần cài thêm gì. Một lệnh là xong:

git config --global credential.helper store

Credentials sẽ được lưu vào ~/.git-credentials ở dạng plaintext:

https://username:[email protected]

Ưu điểm: Zero setup, hoạt động ngay, không phụ thuộc thêm package nào.

Nhược điểm: Token lưu plaintext — bất kỳ process nào chạy với quyền user đều đọc được. Máy bị compromise là token bị lộ hoàn toàn. Không phù hợp với máy shared hoặc production server.

Cách 2: git-credential-cache (lưu tạm trong RAM)

# Lưu credentials trong RAM, timeout sau 1 giờ (3600 giây)
git config --global credential.helper 'cache --timeout=3600'

Ưu điểm: Credentials không ghi ra disk, an toàn hơn store.

Nhược điểm: Reboot là mất, phải nhập lại. Không hoạt động trên hệ thống thiếu Unix socket (một số distro minimal setup). Với server chạy 24/7, cứ mỗi giờ lại phải nhập lại — không thực tế.

Cách 3: libsecret (tích hợp với GNOME Keyring / KWallet)

Trên Ubuntu hay Fedora có GNOME, đây là lựa chọn ngon mà nhiều người hay bỏ qua. libsecret giao tiếp trực tiếp với Secret Service API — credentials được mã hóa bởi OS, không phải bởi app, lưu trong keyring của hệ thống.

# Cài libsecret
sudo apt install libsecret-1-0 libsecret-1-dev git

# Build git-credential-libsecret
cd /usr/share/doc/git/contrib/credential/libsecret
sudo make

# Cấu hình
git config --global credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret

Ưu điểm: Credentials được mã hóa bởi OS, tích hợp sẵn với GNOME/KDE, không cần daemon riêng.

Nhược điểm: Chỉ chạy được khi có desktop environment (GNOME, KDE). Trên headless server, GNOME Keyring không khởi động được — nó cần D-Bus session và GUI environment để hoạt động.

Cách 4: Git Credential Manager (GCM) — Cross-platform

Microsoft build cái này và open source nó. GCM xử lý OAuth2 hoàn chỉnh — không cần tự tạo PAT thủ công, chỉ cần login một lần qua browser là xong. Hỗ trợ GitHub, GitLab, Bitbucket, Azure DevOps đều đủ. Trên Linux, GCM linh hoạt với nhiều backend lưu trữ khác nhau.

Ưu điểm: OAuth2 tự động (không cần PAT thủ công), hoạt động cả desktop lẫn headless server, nhiều backend storage, cross-platform.

Nhược điểm: Cần cài thêm .NET runtime, binary khá nặng (~100MB). Nếu chỉ dùng một service thì hơi overkill.

Phân tích: Nên chọn cách nào?

Tiêu chí store cache libsecret GCM
Bảo mật ❌ Plaintext ✅ RAM only ✅ Encrypted ✅ Encrypted
Persistent
Headless server ✅ (với secret-service hoặc plaintext)
Desktop Linux
OAuth2 tự động
Setup phức tạp Rất dễ Rất dễ Trung bình Trung bình

Kết luận thực tế của mình:

  • Desktop Linux (Ubuntu, Fedora, Mint): Dùng libsecret — native, nhẹ, an toàn, tích hợp luôn với keyring có sẵn.
  • Headless server / VPS: Dùng GCM với GPG-encrypted plaintext store hoặc đơn giản hơn là SSH key (không cần credential helper gì cả).
  • Team nhiều service (GitHub + GitLab + Bitbucket): Dùng GCM cho OAuth2 tự động.

Triển khai: libsecret trên Ubuntu/Debian Desktop

Bước 1: Cài đặt

sudo apt update
sudo apt install libsecret-1-0 libsecret-1-dev git make gcc

Bước 2: Build git-credential-libsecret

# Tìm đường dẫn source (tùy version git)
ls /usr/share/doc/git/contrib/credential/libsecret/

# Build
cd /usr/share/doc/git/contrib/credential/libsecret/
sudo make

# Verify
ls -la git-credential-libsecret

Bước 3: Cấu hình global

git config --global credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret

# Verify cấu hình
cat ~/.gitconfig | grep credential

Lần đầu git push, bạn sẽ được hỏi token. Nhập xong, libsecret lưu vào GNOME Keyring. Từ lần sau trở đi, tự động lấy ra không cần nhập lại.

Triển khai: Git Credential Manager trên Headless Server

Bước 1: Tải và cài GCM

# Kiểm tra release mới nhất tại: https://github.com/git-ecosystem/git-credential-manager/releases
GCM_VERSION="2.5.1"
wget https://github.com/git-ecosystem/git-credential-manager/releases/download/v${GCM_VERSION}/gcm-linux_amd64.${GCM_VERSION}.deb

sudo dpkg -i gcm-linux_amd64.${GCM_VERSION}.deb

Bước 2: Cấu hình backend lưu trữ

Trên headless server, GCM không thể dùng GNOME Keyring. Có 2 lựa chọn:

# Option A: Dùng GPG-encrypted file (khuyến nghị)
git-credential-manager configure
git config --global credential.credentialStore gpg

# Tạo GPG key nếu chưa có
gpg --gen-key

# Option B: Plaintext (tương đương git-credential-store nhưng qua GCM)
git config --global credential.credentialStore plaintext

Bước 3: Test với GitHub

# Clone repo private để test
git clone https://github.com/your-org/private-repo.git

# GCM sẽ mở browser (nếu có) hoặc hiện URL để authenticate
# Sau khi authenticate lần đầu, mọi git operation sau đều tự động

Một tình huống thực tế mình đã gặp

Mình từng mất code quan trọng vì force push nhầm branch — từ đó luôn cẩn thận với git push --force. Nhưng cũng từ incident đó, mình nhận ra mình đang paste token vào terminal một cách thoải mái, không để ý rằng lịch sử terminal có thể lưu lại token đó.

# ĐỪNG làm thế này — token lộ trong history!
git clone https://username:[email protected]/org/repo.git

# Kiểm tra bash history
history | grep ghp_
# → Đây là lý do cần credential helper thay vì inline token

Sau khi chuyển sang libsecret, token không còn xuất hiện trong command line hay history nữa. Git lấy token từ keyring internally — sạch hơn hẳn.

Bonus: Quản lý nhiều tài khoản GitHub cùng lúc

Có cả tài khoản cá nhân lẫn tài khoản công ty trên GitHub? GCM xử lý tốt hơn libsecret trong trường hợp này:

# Cấu hình per-repo (override global)
cd ~/work-project
git config credential.https://github.com.username work-username

# Hoặc dùng SSH với nhiều key (cách mình ưa hơn)
# Thêm vào ~/.ssh/config
Host github-personal
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_personal

Host github-work
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_work

# Clone bằng alias
git clone git@github-personal:username/personal-repo.git
git clone git@github-work:org/work-repo.git

Dọn dẹp credentials cũ

Cần xóa credentials cũ hoặc reset để nhập lại từ đầu — đây là các lệnh tương ứng cho từng method:

# Xóa credentials đã lưu (libsecret)
git credential-libsecret erase
protocol=https
host=github.com
# Nhấn Ctrl+D

# Xóa toàn bộ cache (git-credential-cache)
git credential-cache exit

# Xóa file store thủ công
rm ~/.git-credentials

Tóm lại

Dùng Linux desktop thì cài libsecret trước — nhẹ, native, setup xong trong 10 phút. Quản lý server hoặc phải xử lý nhiều Git service cùng lúc thì GCM xứng đáng với thời gian setup ban đầu. Còn nếu server chỉ cần pull/push từ một repo duy nhất, deploy SSH key và quên credential helper đi cho khỏe — đó là cách mình đang dùng trên hầu hết VPS production.

Share: