IAM คืออะไร?
Identity & Access Management (IAM) คือระบบที่จัดการว่า “ใครเป็นใคร” และ “ใครมีสิทธิ์ทำอะไร” ในระบบคอมพิวเตอร์
ลองนึกภาพตึกสำนักงาน:
- Authentication (AuthN) — “คุณเป็นใคร?” เหมือนรปภ.ตรวจบัตรพนักงานที่ประตูตึก คุณต้องพิสูจน์ตัวตนก่อนจะเข้าได้
- Authorization (AuthZ) — “คุณมีสิทธิ์ทำอะไร?” เหมือนบัตรพนักงานที่กำหนดว่าเข้าชั้นไหนได้บ้าง — พนักงานทั่วไปเข้าได้แค่ชั้น 1-3 แต่ผู้จัดการเข้าได้ถึงชั้น 10
┌──────────────────────────────────────────────────────┐
│ ตึกสำนักงาน │
│ │
│ ┌─────────────────┐ ┌────────────────────────┐ │
│ │ Authentication │ │ Authorization │ │
│ │ (ประตูตึก) │ │ (สิทธิ์แต่ละชั้น) │ │
│ │ │ │ │ │
│ │ "แสดงบัตร" │ ──▶ │ ชั้น 1-3: พนักงาน │ │
│ │ "สแกนนิ้ว" │ │ ชั้น 4-7: หัวหน้าทีม │ │
│ │ "ใส่รหัส OTP" │ │ ชั้น 8-10: ผู้บริหาร │ │
│ └─────────────────┘ └────────────────────────┘ │
└──────────────────────────────────────────────────────┘
ในระบบ IT ก็เหมือนกัน:
- Authentication: login ด้วย username/password, fingerprint, OTP
- Authorization: user A เข้า admin page ได้ แต่ user B เห็นแค่ dashboard
ถ้าไม่มี IAM แต่ละ app ต้องสร้างระบบ login เอง → มี user database แยก → user ต้องจำ password คนละชุดสำหรับแต่ละ app → admin จัดการลำบาก
Keycloak คืออะไร?
Keycloak คือ open-source IAM solution ที่สร้างโดย Red Hat ทำหน้าที่เป็น “ศูนย์กลางจัดการ identity” — สร้าง user ที่เดียว ใช้ login ได้ทุก app ที่เชื่อมไว้
คิดง่ายๆ Keycloak คือ “Google Account ของเรา” — เหมือนที่ login Google ครั้งเดียวแล้วเข้า Gmail, YouTube, Drive ได้หมด แต่แทนที่จะเป็นของ Google เราสร้างระบบนี้เองบน server เรา
ทำไมใช้ Keycloak แทนที่จะเขียน login เอง?
- เขียน auth ดี ≠ ง่าย — ระบบ login ที่ปลอดภัยต้องจัดการ password hashing, brute force protection, token management, session management ผิดขั้นตอนเดียว = โดน hack
- Centralized — แก้ password ที่เดียว ใช้ได้ทุก app
- Standards-based — รองรับ OAuth 2.0, OIDC, SAML ไม่ต้อง reinvent the wheel
- Admin UI — จัดการ users, roles, permissions ผ่าน web interface
Core Concepts
Keycloak จัดโครงสร้างเป็น hierarchy:
Keycloak Server
│
├── Realm: company-a ──────────────────────────
│ │ │
│ ├── Clients (apps ที่เชื่อม) │
│ │ ├── web-app │
│ │ ├── mobile-app │
│ │ └── admin-portal │
│ │ │
│ ├── Users │
│ │ ├── alice (roles: admin, viewer) │
│ │ └── bob (roles: viewer) │
│ │ │
│ ├── Roles │
│ │ ├── admin │
│ │ └── viewer │
│ │ │
│ └── Groups │
│ ├── engineering (role: admin) │
│ └── marketing (role: viewer) │
│ │
└── Realm: company-b ──────────────────────────
│
└── (แยกจาก company-a โดยสิ้นเชิง)
| Concept | คืออะไร | เปรียบเทียบ |
|---|---|---|
| Realm | พื้นที่แยกอิสระ มี users, roles, settings เป็นของตัวเอง | เหมือนบริษัทคนละบริษัท |
| Client | app หรือ service ที่เชื่อมกับ Keycloak เพื่อใช้ login | เหมือนประตูแต่ละบานของตึก |
| User | คนที่ใช้ระบบ | พนักงาน |
| Role | สิทธิ์ที่กำหนดว่าทำอะไรได้ | ตำแหน่งงาน |
| Group | กลุ่มของ users ที่ได้ roles เหมือนกัน | แผนก (assign role ให้ group แทนรายคน) |
ทำไมต้องมี Realm? — ถ้า host Keycloak ให้หลายองค์กร แต่ละ realm แยกจากกันสิ้นเชิง — user ของ company-a เห็น user ของ company-b ไม่ได้ ตั้งค่า security แยกกันได้
Authentication Protocols
Keycloak รองรับ 3 protocols หลัก — ไม่ต้องเลือกอันเดียว ใช้คู่กันได้:
| OAuth 2.0 | OIDC | SAML 2.0 | |
|---|---|---|---|
| ย่อจาก | Open Authorization | OpenID Connect | Security Assertion Markup Language |
| ทำหน้าที่ | Authorization (ให้สิทธิ์) | Authentication + Authorization | Authentication + Authorization |
| Format | JSON (tokens) | JSON (JWT tokens) | XML |
| สร้างเมื่อ | 2012 | 2014 (สร้างบน OAuth 2.0) | 2005 |
| เหมาะกับ | API access, mobile apps | Web apps, SPAs, mobile | Enterprise, legacy systems |
| ความซับซ้อน | ปานกลาง | ปานกลาง | สูง (XML verbose) |
ความสัมพันธ์ระหว่าง OAuth 2.0 กับ OIDC: OAuth 2.0 ถูกออกแบบมาเพื่อ authorization (ให้สิทธิ์เข้าถึง resource) แต่ไม่ได้บอกว่า “user เป็นใคร” OIDC เลยสร้างทับบน OAuth 2.0 เพิ่มส่วน authentication (พิสูจน์ตัวตน) เข้าไป — ส่วนใหญ่ถ้าเริ่มใหม่ เลือก OIDC ได้เลย
OAuth 2.0 Authorization Code Flow
นี่คือ flow ที่ใช้บ่อยที่สุดสำหรับ web app — ปลอดภัยที่สุดเพราะ secret ไม่โดน expose ที่ browser:
┌──────┐ ┌──────────┐ ┌──────────┐
│ User │ │ App │ │ Keycloak │
│(เบราว์│ │(web app) │ │ (IdP) │
│ เซอร์)│ │ │ │ │
└──┬───┘ └────┬─────┘ └────┬─────┘
│ │ │
│ 1. เข้า app │ │
│──────────────────▶│ │
│ │ │
│ 2. redirect ไป Keycloak │
│◀──────────────────│ │
│ │ │
│ 3. หน้า login ของ Keycloak │
│──────────────────────────────────────▶ │
│ │ │
│ 4. user ใส่ username/password │
│──────────────────────────────────────▶ │
│ │ │
│ 5. redirect กลับ app พร้อม auth code │
│◀────────────────────────────────────── │
│ │ │
│ 6. (browser ส่ง code ให้ app) │
│──────────────────▶│ │
│ │ │
│ │ 7. app แลก code │
│ │ เป็น token │
│ │────────────────────▶│
│ │ │
│ │ 8. ได้ access token │
│ │◀────────────────────│
│ │ │
│ 9. login สำเร็จ │ │
│◀──────────────────│ │
ทำไมต้องใช้ “code” แลก “token”? เพราะ:
- ขั้นตอน 5: auth code ผ่าน browser (URL) → มีคนอาจเห็นได้
- ขั้นตอน 7: แลก code เป็น token ทำ server-to-server → ไม่ผ่าน browser → ปลอดภัยกว่า
- Auth code ใช้ได้ครั้งเดียว + หมดอายุเร็ว → ถ้าถูกขโมยก็ใช้ไม่ได้
Token Types
หลังจาก login สำเร็จ Keycloak จะส่ง tokens กลับมา 3 ชนิด:
| Token | อายุ | ทำหน้าที่ | เปรียบเทียบ |
|---|---|---|---|
| Access Token | สั้น (5-15 นาที) | ใช้เข้าถึง API/resource แนบไปกับทุก request | บัตรผ่านชั่วคราว |
| Refresh Token | ยาว (30 นาที - หลายวัน) | ใช้ขอ access token ใหม่โดยไม่ต้อง login ซ้ำ | บัตรที่ใช้ต่ออายุบัตรผ่าน |
| ID Token | สั้น (เท่า access token) | ข้อมูลของ user (ชื่อ, email, roles) | บัตรประจำตัว |
JWT คืออะไร? — JSON Web Token เป็น format ของ token ที่ใช้กันทั่วไป หน้าตาเป็น string 3 ส่วนคั่นด้วยจุด:
header.payload.signature
eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJhbGljZSIsInJvbGVzIjpbImFkbWluIl19.signature
(header) (payload = ข้อมูลจริง) (ลายเซ็น)
Payload (ส่วนกลาง) เก็บข้อมูลสำคัญ:
{
"sub": "alice",
"email": "alice@example.com",
"roles": ["admin"],
"exp": 1709312400
}
sub— subject (user ID)exp— expiration time (หมดอายุเมื่อไหร่)roles— สิทธิ์ของ user
ข้อสำคัญ: JWT ถูก signed (เซ็นด้วย private key ของ Keycloak) แต่ ไม่ได้ encrypt ใครก็ decode ดู payload ได้ ดังนั้นอย่าใส่ข้อมูล sensitive ใน token เช่น password
SSO (Single Sign-On)
SSO คือความสามารถที่ login ครั้งเดียว แล้วเข้าได้ทุก app ที่เชื่อมกับ Keycloak:
┌──────────┐
┌──────▶│ App A │ ← เข้าได้เลย (มี session แล้ว)
│ └──────────┘
│
┌──────┐ │ ┌──────────┐
│ User │────┼──────▶│ App B │ ← เข้าได้เลย (ไม่ต้อง login อีก)
│ │ │ └──────────┘
└──┬───┘ │
│ │ ┌──────────┐
│ login └──────▶│ App C │ ← เข้าได้เลย
│ ครั้งเดียว └──────────┘
│
▼
┌──────────┐
│ Keycloak │ ← จัดการ session กลาง
└──────────┘
วิธีทำงาน:
- User เข้า App A → ยังไม่มี session → redirect ไป Keycloak
- User login ที่ Keycloak → Keycloak สร้าง SSO session (เก็บเป็น cookie)
- Keycloak redirect กลับ App A พร้อม token → เข้า App A ได้
- User เข้า App B → ยังไม่มี token → redirect ไป Keycloak
- Keycloak เห็นว่ามี SSO session อยู่แล้ว → ไม่ต้อง login อีก → ส่ง token กลับ App B เลย
ข้อดี:
- User จำ password แค่ชุดเดียว
- Admin จัดการ user ที่เดียว — ลบ user ออกจาก Keycloak = หลุดจากทุก app ทันที
- ปลอดภัยกว่า — MFA (Multi-Factor Authentication) ตั้งครั้งเดียวใช้ทุก app
User Federation
ถ้าองค์กรมี user อยู่แล้วใน LDAP หรือ Active Directory ไม่ต้องย้าย user มาใส่ Keycloak — ใช้ User Federation เชื่อมเข้าด้วยกันได้:
┌──────────┐ ┌──────────┐ ┌──────────┐
│ User │──login─▶│ Keycloak │──query──▶│ LDAP │
│ │ │ │ │ (user DB │
│ │◀─token──│ │◀─result──│ เดิม) │
└──────────┘ └──────────┘ └──────────┘
- User login ที่ Keycloak → Keycloak ไปเช็ค username/password กับ LDAP
- ถ้าถูก → Keycloak ออก token ให้
- User ไม่ต้องรู้ด้วยซ้ำว่า LDAP อยู่ข้างหลัง
- Admin จัดการ user ที่ LDAP เหมือนเดิม
สนใจเรื่อง LDAP เพิ่มเติม อ่านต่อได้ที่ LDAP: ทำความเข้าใจ Directory Service ตั้งแต่พื้นฐาน
Identity Brokering
นอกจาก user/password แล้ว Keycloak ยังเป็น Identity Broker ได้ — คือให้ user login ผ่าน provider อื่น เช่น Google, GitHub, Facebook:
User กด "Login with Google"
│
▼
┌────────────────┐
│ Keycloak │ ── redirect ──▶ Google
│ (Identity │ │
│ Broker) │ ◀── user info ────┘
│ │
│ สร้าง/map user │
│ ใน Keycloak │
└────────┬───────┘
│
▼
ออก token ให้ app
วิธีทำงาน:
- User กด “Login with Google” ที่หน้า login ของ Keycloak
- Keycloak redirect ไป Google → user login กับ Google
- Google ส่ง user info (email, name) กลับมาที่ Keycloak
- Keycloak สร้าง user ใหม่ (หรือ map กับ user ที่มีอยู่) → ออก token ของ Keycloak ให้ app
ข้อดี: app ไม่ต้องเชื่อม Google/GitHub เอง — Keycloak จัดการให้หมด ถ้าวันหนึ่งอยากเพิ่ม “Login with LINE” ก็แค่ตั้งค่าใน Keycloak ไม่ต้องแก้ code ใน app
OAuth2-Proxy Pattern
ปัญหา: มี app เก่าๆ หรือ open-source app (เช่น Grafana, n8n) ที่อยากใส่ Keycloak authentication แต่ไม่อยากแก้ code ของ app
วิธีแก้: ใช้ OAuth2 Proxy เป็น reverse proxy วางหน้า app — ทำหน้าที่เช็ค authentication ก่อนปล่อยเข้า app:
┌────────────────────────────────────────────────────────┐
│ Kubernetes Pod │
│ │
│ ┌──────────────┐ ┌────────────────────────────┐ │
│ │ OAuth2 Proxy │ ────▶│ App (เช่น Grafana) │ │
│ │ (sidecar) │ │ │ │
│ │ │ │ ไม่ต้องรู้เรื่อง auth เลย │ │
│ │ ตรวจ token │ │ รับ traffic ที่ผ่านแล้ว │ │
│ │ redirect │ └────────────────────────────┘ │
│ │ login │ │
│ └──────┬───────┘ │
│ │ │
└─────────┼──────────────────────────────────────────────┘
│
▼
┌──────────┐
│ Keycloak │
└──────────┘
Flow:
- User เข้า
app.example.com→ request ไปถึง OAuth2 Proxy ก่อน - OAuth2 Proxy เช็ค: มี valid token ไหม?
- ไม่มี → redirect ไป Keycloak login
- มี → ส่ง request ต่อไป app ข้างหลัง
- App ได้รับเฉพาะ request ที่ผ่าน authentication แล้ว
ข้อดี:
- App ไม่ต้องเขียน auth logic แม้แต่บรรทัดเดียว
- เพิ่ม/ถอด authentication ได้โดยไม่แตะ code ของ app
- ใช้ pattern เดียวกันกับทุก app บน cluster
Keycloak Architecture บน Kubernetes
เมื่อ deploy Keycloak บน Kubernetes architecture หน้าตาเป็นแบบนี้:
Internet
│
▼
┌────────────────────────────┐
│ Ingress Controller │ ← Traefik
│ (route domain → service) │
└─────────────┬──────────────┘
│
▼
┌────────────────────────────┐
│ Keycloak Pod(s) │ ← stateless, scale ได้
│ auth.example.com │
│ │
│ - Realm config │
│ - Token signing keys │
│ - Session management │
└─────────────┬──────────────┘
│
▼
┌────────────────────────────┐
│ PostgreSQL │ ← เก็บ users, realms, sessions
│ (Persistent Volume) │
└────────────────────────────┘
สิ่งสำคัญ:
- Keycloak เป็น stateless — state ทั้งหมดอยู่ใน database ทำให้ scale ได้ง่าย (เพิ่ม pod)
- PostgreSQL — เก็บ users, realms, client configs ต้องมี persistent storage
- TLS (HTTPS) — Keycloak จัดการ token ดังนั้น traffic ระหว่าง user กับ Keycloak ต้อง encrypt เสมอ
- Ingress — domain เช่น
auth.example.comroute เข้ามาที่ Keycloak pods
Security Best Practices
| หัวข้อ | แนวทาง | ทำไม |
|---|---|---|
| Token lifetime | Access token 5-15 นาที, refresh token 30 นาที - 8 ชม. | ถ้า token หลุด ผลกระทบจำกัด |
| HTTPS เท่านั้น | บังคับ HTTPS ทุก endpoint ของ Keycloak | token ที่ส่งผ่าน HTTP ถูกดักอ่านได้ |
| Brute force protection | เปิด account lockout หลัง N ครั้งที่ login ผิด | ป้องกันการเดา password |
| Password policy | กำหนดความยาวขั้นต่ำ, ห้ามซ้ำกับ N passwords ก่อนหน้า | ลดความเสี่ยงจาก weak password |
| MFA (Multi-Factor) | เปิด OTP/TOTP เป็น required สำหรับ admin | แม้ password หลุด ยังเข้าไม่ได้ |
| Admin account | สร้าง admin user แยก ไม่ใช้ default | default credentials ถูกเดาง่าย |
| Client secrets | เก็บ client secret ใน secret manager (เช่น Vault) | ไม่ hardcode ใน config file |
| Audit logging | เปิด event logging สำหรับ login events | ตรวจสอบย้อนหลังได้เมื่อมีเหตุผิดปกติ |
สรุป
| หัวข้อ | สิ่งที่ Keycloak จัดการให้ |
|---|---|
| Authentication | Login ด้วย username/password, social login, MFA |
| Authorization | Roles, Groups, fine-grained permissions |
| SSO | Login ครั้งเดียว ใช้ได้ทุก app |
| User Federation | เชื่อม LDAP/Active Directory ใช้ user ที่มีอยู่แล้ว |
| Identity Brokering | Login with Google, GitHub, LINE ฯลฯ |
| Token Management | ออก JWT tokens, จัดการ refresh, revoke |
| Admin Console | จัดการ users, roles, clients ผ่าน web UI |
| Standards | OAuth 2.0, OIDC, SAML 2.0 |
Keycloak ช่วยให้ developer โฟกัสที่ feature ของ app แทนที่จะเสียเวลาเขียนระบบ login เอง — และที่สำคัญคือปลอดภัยกว่า เพราะ Keycloak ถูก audit และ maintain โดย community ขนาดใหญ่
ถ้าสนใจเรื่อง LDAP ที่ใช้คู่กับ Keycloak ในส่วน User Federation อ่านต่อได้ที่ LDAP: ทำความเข้าใจ Directory Service ตั้งแต่พื้นฐาน — อธิบายตั้งแต่ Directory Service คืออะไร ไปจนถึงโครงสร้าง DIT และ LDAP operations