Roles
role คืออะไร?
หัวข้อที่มีชื่อว่า “role คืออะไร?”role คือป้ายสิทธิ์ (permission tag) ที่มีชื่อ ซึ่งคุณผูกเข้ากับ user (หรือ group) เมื่อ user ยืนยันตัวตน Keycloak จะฝัง role ของพวกเขาไว้ใน token แอปพลิเคชันของคุณอ่าน role เหล่านั้นจาก token แล้วตัดสินใจว่า user ได้รับอนุญาตให้ทำอะไรได้บ้าง — โดยไม่ต้องเรียก database เพิ่มเติม
Keycloak มี role อยู่สองแบบ:
- Realm role — กำหนดที่ระดับ realm ใช้ได้กับทุก client ใน realm
- Client role — กำหนดบน client เฉพาะตัว จำกัดขอบเขตอยู่ที่ client นั้น
Realm role
หัวข้อที่มีชื่อว่า “Realm role”realm role มีผลทั่วทั้ง realm เหมาะกับสิทธิ์แบบหยาบ (coarse-grained) ที่ใช้ทั้งแอปพลิเคชัน เช่น admin, support-agent หรือ billing-viewer ที่อาจเกี่ยวข้องกับแอปพลิเคชันมากกว่าหนึ่งตัว
การสร้าง realm role
หัวข้อที่มีชื่อว่า “การสร้าง realm role”- ใน admin console ตรวจสอบให้แน่ใจว่าคุณอยู่ใน realm ที่ถูกต้อง
- คลิก Realm roles ในแถบด้านซ้าย
- คลิก Create role (มุมบนขวาของรายการ)
- ใส่ Role name (เช่น
app-admin) - เพิ่ม Description ก็ได้ (ไม่บังคับ)
- คลิก Save
ตอนนี้ role พร้อมแล้วสำหรับนำไปกำหนดให้กับ user, group หรือ composite role
Client role
หัวข้อที่มีชื่อว่า “Client role”client role ถูกกำหนดบน client เฉพาะตัวและมีความหมายเฉพาะกับ client นั้นเท่านั้น เหมาะกับสิทธิ์แบบละเอียด (fine-grained) ที่เจาะจงกับแอปพลิเคชัน เช่น orders:read, orders:write หรือ reports:export
การสร้าง client role
หัวข้อที่มีชื่อว่า “การสร้าง client role”- ใน admin console คลิก Clients ในแถบด้านซ้าย แล้วเปิด client ที่คุณต้องการเพิ่ม role
- คลิกแท็บ Roles บน client
- คลิก Create role
- ใส่ Role name (เช่น
orders:read) - เพิ่ม Description ก็ได้ (ไม่บังคับ)
- คลิก Save
Composite role
หัวข้อที่มีชื่อว่า “Composite role”composite role คือ role ที่ให้สิทธิ์ทุก role ที่บรรจุอยู่โดยอัตโนมัติ แทนที่จะกำหนด role ห้าตัวแยกกันให้พนักงานใหม่ทุกคน คุณสร้าง composite role หนึ่งตัว (employee) ที่รวมทั้งหมดเข้าด้วยกัน แล้วกำหนดเพียงตัวเดียว
การสร้าง composite role
หัวข้อที่มีชื่อว่า “การสร้าง composite role”- สร้าง child role ก่อน (realm role หรือ client role)
- สร้าง realm role ใหม่ (เช่น
employee) - ในหน้ารายละเอียดของ role ให้คลิก Action → Add associated roles (หรือมองหาแท็บ Associated roles)
- ค้นหาและเลือก child role ที่คุณต้องการรวมเข้าด้วยกัน
- คลิก Assign
ตอนนี้การกำหนด employee ให้กับ user จะให้สิทธิ์ทุก role ที่รวมไว้โดยอัตโนมัติ
การกำหนด role ให้กับ user
หัวข้อที่มีชื่อว่า “การกำหนด role ให้กับ user”- ใน admin console คลิก Users ในแถบด้านซ้าย
- หา user แล้วคลิกที่ username เพื่อเปิดโปรไฟล์ของพวกเขา
- คลิกแท็บ Role mapping
- คลิก Assign role
- ในตัวกรอง ให้เลือก Filter by realm roles เพื่อดู realm role หรือ Filter by clients แล้วเลือก client ของคุณเพื่อดู client role
- ติ๊กช่องข้างแต่ละ role ที่คุณต้องการกำหนด
- คลิก Assign
role จะมีผลทันทีสำหรับ login session ใหม่ session ที่มีอยู่เดิมจะไม่ถูกอัปเดตย้อนหลังจนกว่า user จะยืนยันตัวตนใหม่หรือ token ของพวกเขาถูก refresh
role ปรากฏใน token อย่างไร
หัวข้อที่มีชื่อว่า “role ปรากฏใน token อย่างไร”หลังจาก user ยืนยันตัวตน access token ของพวกเขา (ที่เป็น JWT) จะมี role อยู่ใน claim มาตรฐานสองตัว:
realm_access.roles— array ของ realm-level role ทั้งหมดที่กำหนดให้ userresource_access.{client-id}.roles— array ของ client role สำหรับ client เฉพาะตัวนั้น
นี่คือ payload ของ JWT ที่ถอดรหัสแล้วซึ่งแสดงทั้งสองแบบ:
{
"sub": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"preferred_username": "alice",
"email": "[email protected]",
"realm_access": {
"roles": [
"app-admin",
"offline_access",
"uma_authorization"
]
},
"resource_access": {
"my-app-backend": {
"roles": [
"orders:read",
"orders:write"
]
},
"account": {
"roles": [
"manage-account",
"view-profile"
]
}
}
}การอ่าน role ในแอปพลิเคชันของคุณ
หัวข้อที่มีชื่อว่า “การอ่าน role ในแอปพลิเคชันของคุณ”แอปพลิเคชันของคุณควรตรวจสอบ JWT signature โดยใช้ JWKS endpoint ของ realm จากนั้นจึงอ่าน role จาก claim ที่แสดงข้างต้น ไลบรารี OIDC ส่วนใหญ่ (Keycloak adapter, Spring Security, Passport.js ฯลฯ) จะทำสิ่งนี้ให้โดยอัตโนมัติเมื่อตั้งค่าแล้ว คุณไม่ควรเชื่อ token โดยไม่ตรวจสอบ signature เด็ดขาด
ตัวอย่าง: ในแอปพลิเคชัน Node.js ที่ใช้ JWT payload ดิบหลังการตรวจสอบ:
// After jwt.verify() succeeds:const realmRoles = token.realm_access?.roles ?? [];const clientRoles = token.resource_access?.['my-app-backend']?.roles ?? [];
if (realmRoles.includes('app-admin')) { // grant admin access}role ที่มีมาในตัวของ Keycloak
หัวข้อที่มีชื่อว่า “role ที่มีมาในตัวของ Keycloak”ทุก realm และทุก client มาพร้อม role ที่มีในตัวบางส่วนซึ่งคุณจะเห็นใน token:
| Role | ที่อยู่ | จุดประสงค์ |
|---|---|---|
offline_access | Realm | อนุญาตให้ขอ offline token (refresh token ที่มีอายุยาว) |
uma_authorization | Realm | ให้สิทธิ์เข้าถึง UMA authorisation API |
manage-account | account client | ให้ user จัดการบัญชีของตัวเองได้ |
view-profile | account client | ให้ user ดูโปรไฟล์ของตัวเองได้ |
คุณไม่จำเป็นต้องกำหนด uma_authorization หรือ offline_access ให้ user ด้วยตนเอง; role เหล่านี้ถูกให้สิทธิ์โดยค่าเริ่มต้นผ่าน composite role ชื่อ default-roles-{realm}
ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
| Realm role | ใช้ได้ทั่วทุก client ใน realm เหมาะกับสิทธิ์แบบหยาบที่ใช้ร่วมกันข้ามแอป | ไม่สามารถจำกัดขอบเขตไปยัง client ใด client หนึ่งได้ ต้องพึ่ง client role ถ้าต้องการความละเอียด |
| Client role | จำกัดขอบเขตอยู่ที่ client เดียว เหมาะกับสิทธิ์แบบละเอียดที่เจาะจงกับแอปพลิเคชัน (เช่น orders:write) | ต้องกำหนดซ้ำในทุก client ที่มีสิทธิ์คล้ายกัน จัดการยากขึ้นเมื่อมีหลาย client |
| Group + role vs กำหนด role ตรงให้ user | มอบหมาย role ให้คนจำนวนมากพร้อมกันผ่าน group เดียว จัดการง่ายเมื่อมีคนเข้า-ออกทีมบ่อย | ต้องออกแบบโครงสร้าง group ล่วงหน้าให้ดี ถ้าโครงสร้างผิดจะแก้ทีหลังยาก |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”- กำหนด role ให้ user ทีละคนแทนที่จะใช้ group — เมื่อมีพนักงานเข้าใหม่หรือเปลี่ยนตำแหน่งบ่อย การไล่กำหนด role ทีละคนทำให้เกิดความผิดพลาดและ role ตกหล่นได้ง่าย ควรผูก role เข้ากับ group แล้วกำหนด user เข้า group แทน
- ใช้ client role ทั้งหมดโดยไม่มี realm role เลย แม้สิทธิ์นั้นใช้ร่วมกันหลายแอป — ทำให้ต้องกำหนด role ซ้ำ ๆ ในทุก client เมื่อจริง ๆ ควรยกสิทธิ์ที่ใช้ร่วมกันขึ้นไปเป็น realm role
- ลืมว่า role ใหม่จะไม่มีผลกับ session เดิมทันที — ทีมมักเข้าใจผิดว่าการกำหนด role ใหม่จะมีผลทันที ทั้งที่ user ต้อง login ใหม่หรือรอ token refresh ก่อน ทำให้เข้าใจผิดว่าการตั้งค่า “ไม่ทำงาน”
💡 ตัวอย่างจากของจริง
GitHub Organizations — ใช้แนวคิดคล้าย realm role กับ team-scoped permission โดยสิทธิ์ระดับ organization (เช่น owner, member) ใช้ได้ทั่วทุก repository ส่วนสิทธิ์ระดับ repository ทำหน้าที่คล้าย client role ที่จำกัดขอบเขตแคบลง
Enterprise onboarding ผ่าน group — องค์กรขนาดใหญ่จำนวนมากผูก composite role เข้ากับ group ตามแผนก (เช่น
engineering,sales) เมื่อพนักงานใหม่เข้าทีม HR system เพียงเพิ่ม user เข้า group ที่ถูกต้อง role ทั้งหมดของแผนกนั้นก็ถูกกำหนดให้อัตโนมัติผ่าน Keycloak