Bài toán thực tế: Nhân viên nghỉ, ai xóa tài khoản?
Đầu năm ngoái mình tham gia audit bảo mật cho một công ty 30 người. Họ dùng GitLab, Jira, Confluence, Grafana, Kibana và 6 server Linux. Khi check lại, phát hiện 3 tài khoản của nhân viên đã nghỉ 6 tháng trước vẫn còn active trên GitLab — một trong số đó có quyền Maintainer.
Không ai cố tình để sót. Đơn giản là không có quy trình tập trung: offboard thủ công qua 10 hệ thống khác nhau, quên một cái là bình thường. Identity Provider (IdP) sinh ra để giải bài toán này — một nơi quản lý tất cả user, một lần đăng nhập dùng được khắp nơi (SSO), xóa một chỗ là mất quyền khắp nơi.
So sánh 4 hướng tiếp cận
1. Quản lý tài khoản thủ công
Mỗi app một bộ username/password riêng. Không cần setup gì, dùng ngay từ ngày đầu.
Vấn đề phát sinh sau 6 tháng: nhân viên bắt đầu đặt mật khẩu giống nhau ở nhiều nơi, hoặc dùng 123456 cho các app “ít quan trọng”. IT phải nhớ danh sách 10–15 hệ thống cần xóa khi ai đó nghỉ việc. Audit log nằm rải rác, không thể theo dõi ai làm gì trên toàn hệ thống.
2. LDAP / Active Directory
Chuẩn công nghiệp từ thời Windows Server 2000. Active Directory tích hợp rất tốt với hệ sinh thái Microsoft và nhiều enterprise software.
Nhưng nếu stack của bạn là Linux và open source: OpenLDAP không có giao diện web thân thiện, cấu hình bằng LDIF khá rối. Active Directory thì cần license Windows Server và Domain Controller chạy Windows. Ngoài ra, cả hai đều không có SSO web-based hay OIDC/OAuth2 built-in — phải ghép thêm component khác.
3. Cloud IAM: Okta, Auth0, Azure Entra ID
Managed service, không cần tự vận hành server. Tích hợp sẵn với hàng ngàn ứng dụng, provisioning tự động, audit log tập trung, MFA có sẵn — setup nhanh trong ngày.
Nhưng con số lại khác: Okta Workforce Identity khoảng $6/user/tháng — 50 người là $3.600/năm, chưa tính các add-on. Auth0 có free tier nhưng giới hạn 7.500 active user và thiếu nhiều tính năng enterprise. Với công ty có yêu cầu compliance về data residency, dữ liệu user nằm trên server vendor ở nước ngoài là điểm vướng thực sự.
4. Self-hosted Identity Provider
Dữ liệu nằm trong tay mình, không phụ thuộc vendor, không có phí per-user. Đổi lại: phải tự vận hành, tự backup, tự xử lý khi có sự cố. Hai cái tên phổ biến nhất trong mảng này là Keycloak và Authentik.
Authentik vs Keycloak: Chọn cái nào?
Keycloak là lựa chọn lâu đời hơn, ecosystem lớn, nhiều tài liệu enterprise. Nhưng setup khá nặng — mặc định chạy với Quarkus, tốn nhiều RAM, và giao diện admin phức tạp với nhiều khái niệm cần học (Realm, Client, Flow, Scope…).
Authentik xuất hiện sau, viết bằng Python/Django + Vue.js. Giao diện trực quan hơn nhiều, tài liệu đọc được mà không cần Google liên tục. Điểm khác biệt lớn nhất là Outpost — forward-auth proxy đặt trước bất kỳ web app nào, bảo vệ ngay cả những app không hỗ trợ OIDC/SAML. Portainer Community Edition hay Kibana cũ không có OIDC? Đặt Outpost trước là xong.
Nói thẳng: mới bắt đầu với IdP, muốn dựng xong trong một buổi chiều — chọn Authentik. Đội đã quen Keycloak và cần tích hợp SAP hay Oracle? Keycloak vẫn phù hợp hơn.
Triển khai Authentik trên Docker
Yêu cầu chuẩn bị
- Server Linux với Docker và Docker Compose đã cài (xem tài liệu Docker chính thức)
- Domain trỏ về server — ví dụ:
auth.company.com - SSL certificate (dùng Certbot nếu chưa có — blog đã có bài riêng)
- Ít nhất 2 GB RAM (PostgreSQL + Redis + server + worker)
Bước 1: Tải file cấu hình và tạo biến môi trường
mkdir -p /opt/authentik && cd /opt/authentik
wget https://goauthentik.io/docker-compose.yml
Tạo file .env với các secret cần thiết:
# Sinh secret key ngẫu nhiên
echo "PG_PASS=$(openssl rand -base64 36)" >> .env
echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60)" >> .env
Ở bước này mình hay dùng thêm password generator tại toolcraft.app để tạo mật khẩu mạnh cho PostgreSQL. Công cụ chạy 100% trên trình duyệt — không gửi request về server, nên không lo lộ mật khẩu qua mạng như các tool online thông thường.
Bước 2: Xem cấu trúc docker-compose.yml
File tải về đã sẵn sàng cho production. Các service chính:
services:
postgresql:
image: docker.io/library/postgres:16-alpine
environment:
POSTGRES_PASSWORD: ${PG_PASS:?database password required}
POSTGRES_USER: ${PG_USER:-authentik}
POSTGRES_DB: ${PG_DB:-authentik}
redis:
image: docker.io/library/redis:alpine
server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.10.4}
command: server
ports:
- "9000:9000" # HTTP
- "9443:9443" # HTTPS
worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.10.4}
command: worker
Bước 3: Khởi động và tạo tài khoản admin
# Kéo image và chạy
docker compose pull
docker compose up -d
# Theo dõi log để chắc chắn server đã sẵn sàng
docker compose logs -f server
Chờ khoảng 2–3 phút. Khi thấy log ... Running là server đã sẵn sàng. Truy cập https://auth.company.com/if/flow/initial-setup/ để đặt mật khẩu cho tài khoản akadmin.
Bước 4: Tích hợp ứng dụng đầu tiên với OAuth2/OIDC
Ví dụ tích hợp GitLab để nhân viên dùng một tài khoản đăng nhập cả hai. Trong Authentik Admin UI, vào Applications → Create with Wizard:
- Name:
GitLab - Provider type: OAuth2/OpenID Connect
- Redirect URI:
https://gitlab.company.com/users/auth/openid_connect/callback - Signing Key: chọn key mặc định
Sau khi tạo, copy Client ID và Client Secret từ phần Provider settings. Thêm vào /etc/gitlab/gitlab.rb:
gitlab_rails['omniauth_providers'] = [
{
name: 'openid_connect',
label: 'Authentik SSO',
args: {
name: 'openid_connect',
scope: ['openid', 'profile', 'email'],
response_type: 'code',
issuer: 'https://auth.company.com/application/o/gitlab/',
discovery: true,
uid_field: 'preferred_username',
client_options: {
identifier: 'YOUR_CLIENT_ID',
secret: 'YOUR_CLIENT_SECRET',
redirect_uri: 'https://gitlab.company.com/users/auth/openid_connect/callback'
}
}
}
]
gitlab-ctl reconfigure
Bước 5: Bật MFA bắt buộc cho toàn bộ user
Vào Flows & Stages → mở flow default-authentication-flow → thêm Stage Authenticator Validation với cấu hình:
- Device classes: TOTP Authenticators (Google Authenticator, Authy…)
- Not configured action: Force the user to configure an authenticator
Từ đây, lần đầu đăng nhập user sẽ bị yêu cầu setup TOTP trước khi vào được bất kỳ app nào — MFA được enforce ở cấp IdP, không cần cấu hình từng app riêng lẻ.
Điều rút ra sau vài tháng chạy thực tế
Mình chạy Authentik cho team ~15 người trên VPS 4 GB RAM, thực tế dùng khoảng 1.5 GB khi idle. Năm tháng chưa một lần restart ngoài ý muốn. Gain lớn nhất: offboard nhân viên chỉ cần disable một user trong Authentik, tự động mất quyền trên tất cả app tích hợp SSO. Từ 30 phút xuống còn 30 giây — không cần checklist 10+ hệ thống nữa.
Điều cần nhớ nhất: backup PostgreSQL đều đặn. Toàn bộ cấu hình, flow, application, user đều nằm ở đó — mất database là dựng lại từ đầu.
# Thêm vào crontab để backup hàng ngày
0 2 * * * docker exec authentik-postgresql-1 pg_dump -U authentik authentik > /backup/authentik-$(date +%Y%m%d).sql
Với các app không hỗ trợ OIDC/SAML — Portainer Community Edition, Kibana phiên bản cũ, hay bất kỳ web app nội bộ nào — Authentik Outpost xử lý được. Đặt làm forward-auth proxy trước app, xác thực đi qua IdP mà không cần chạm vào code app đó. Keycloak không có tính năng này built-in.
