01
Phase 1: Basic • Foundation

Day 1: What is Keycloak? Anatomy, Quarkus Runtime & First Realm

Phase 1 Index ↗ Beginner Friendly Constructive Alignment: 100%
Module 01 • First Principles เริ่มต้นจากศูนย์: ปรับความเข้าใจพื้นฐาน

1. Keycloak คืออะไรกันแน่? ทำไมโลกซอฟต์แวร์สมัยใหม่ถึงต้องใช้มัน?

ลองจินตนาการถึงโลกของการพัฒนาเว็บหรือแอปพลิเคชันในอดีต: เมื่อใดก็ตามที่คุณสร้างโปรเจกต์ใหม่ ไม่ว่าจะเป็นเว็บขายของ, ระบบหลังบ้าน หรือโมบายแอป คุณมักจะต้องเขียนโค้ดชุดเดิมซ้ำๆ เสมอ ได้แก่: หน้าฟอร์มล็อกอิน, ตารางเก็บรหัสผ่านใน Database, ฟังก์ชันแฮชรหัสผ่าน (Bcrypt/Argon2), ระบบส่งอีเมลรีเซ็ตรหัสผ่าน, ระบบจำกัดสิทธิ์ Admin/User และระบบส่ง SMS ยืนยัน OTP

ผลลัพธ์คือ ทุกทีมเขียนระบบล็อกอินของตัวเอง และมักทำผิดพลาดด้านความปลอดภัย (เช่น แฮชรหัสผ่านไม่ปลอดภัย, เซสชันหลุด, โดนแฮกฐานข้อมูลผู้ใช้) แถมเมื่อองค์กรมี 10 แอปพลิเคชัน ผู้ใช้งานคนเดิมกลับต้องมาคอยจำรหัสผ่านถึง 10 ชุด!

❌ โลกเดิม (ไม่มีระบบ IAM กลาง)
  • แต่ละแอปพลิเคชันต้องเขียนระบบ Login และทำฐานข้อมูล User ของตัวเอง
  • รหัสผ่านกระจัดกระจายหลายที่ หากแอปใดโดนเจาะ ข้อมูลผู้ใช้จะรั่วไหลทันที
  • ไม่มีระบบ Single Sign-On (SSO): ผู้ใช้เข้าเว็บหนึ่งแล้ว พอจะไปอีกเว็บหนึ่งต้องพิมพ์ล็อกอินใหม่
  • การเพิ่มฟีเจอร์อย่าง 2FA (OTP) หรือ Google Login ต้องเขียนโค้ดใหม่ทุกแอปพลิเคชัน
✅ โลกที่มี Keycloak (Centralized IAM)
  • Single Sign-On (SSO): ล็อกอินครั้งเดียวผ่านเบราว์เซอร์ สามารถเข้าถึงทุกระบบในเครือได้ทันที
  • Decoupled Security: หน้าเว็บและ API ไม่ต้องแตะต้องรหัสผ่านของผู้ใช้เลย ผลักหน้าที่ตรวจสอบตัวตนให้ Keycloak ทั้งหมด
  • มาตรฐานระดับโลก: รองรับ OpenID Connect (OIDC), OAuth 2.0 และ SAML 2.0 ครบถ้วนโดยไม่ต้องเขียนโค้ดเพิ่ม
  • ความปลอดภัยสำเร็จรูป: มีระบบตรวจจับ Brute Force, รีเซ็ตรหัสผ่าน, 2FA/WebAuthn และ Social Login ให้พร้อมใช้ในคลิกเดียว
นิยามอย่างเป็นทางการ (Root Technical Definition): Keycloak คือซอฟต์แวร์โอเพนซอร์สประเภท Identity and Access Management (IAM) ระดับองค์กร พัฒนาขึ้นด้วยภาษา Java บน Quarkus Runtime ทำหน้าที่เป็นตัวกลางในการยืนยันตัวตน (Authentication) และการอนุญาตกำหนดสิทธิ์ (Authorization) ให้กับแอปพลิเคชันและบริการต่างๆ ตามมาตรฐานสากล (โดย Keycloak เป็นโครงการเรือธงภายใต้การสนับสนุนหลักของ Red Hat)

⚙️ กายวิภาคภายใน: Keycloak ประกอบด้วย 7 ส่วนการทำงานหลัก (Core Subsystems)

Keycloak ไม่ใช่แค่แอปจัดการ Database ธรรมดา แต่คือระบบปฏิบัติการด้าน Identity ที่มีเครื่องใน 7 ส่วนทำงานสอดประสานกัน:

Core Subsystem ชื่อภาษาไทย หน้าที่หลัก & บทบาททางวิศวกรรม
1. Protocol Engine ตัวประมวลผลโปรโตคอล จัดการเส้นทาง Endpoint ตามมาตรฐาน RFC (OIDC, OAuth 2.0, SAML) รับผิดชอบการออก JWT Token, แลกเปลี่ยน Authorization Code, ตรวจ Signature และเสิร์ฟ Public Key ที่ /.well-known
2. Authentication Engine กลไกควบคุมขั้นตอนการล็อกอิน ควบคุม Flow การยืนยันตัวตน (เช่น รหัสผ่าน, OTP, WebAuthn/Passkey, SMS) และตัดสินใจว่าจะให้ผ่าน (Success), ล้มเหลว (Failure) หรือต้องทำขั้นตอนเสริม (Challenge)
3. Identity Brokering & Federation ตัวเชื่อมต่ออัตลักษณ์ภายนอก เชื่อมโยงกับฐานข้อมูลพนักงานเดิมขององค์กรผ่าน LDAP / Active Directory และส่งต่อการล็อกอินไปหาผู้ให้บริการภายนอก (Google, Apple, Microsoft Entra ID)
4. Authorization Services (UMA 2.0) ระบบบริหารสิทธิ์แบบละเอียด ควบคุม Fine-Grained Permissions ได้ลึกระดับ Resource, Scope, Policy, และ Permission ไม่จำกัดแค่ Role ธรรมดา
5. Caching & Session Grid (Infinispan) คลัสเตอร์แคชและจัดการเซสชัน จัดเก็บข้อมูลชั่วคราวที่มีการอัปเดตตลอดเวลา เช่น Active User Sessions, Login Failures และ Token Caches บน Memory ความเร็วสูง พร้อมซิงก์ข้อมูลข้าม Node แบบ Distributed Grid
6. Management & UI Layer ส่วนจัดการและหน้าต่างผู้ใช้ ประกอบด้วย Admin Console สำหรับผู้ดูแลระบบ, Account Console ให้ผู้ใช้แก้ไขข้อมูลตนเอง และ Admin REST API สำหรับควบคุมผ่านโค้ดอัตโนมัติ
7. SPI Extension Framework โครงสร้างปลั๊กอินขยายระบบ สถาปัตยกรรมเปิดที่ยอมให้นักพัฒนาเขียนโค้ดภาษา Java เพื่อสร้างปลั๊กอินเฉพาะทาง (เช่น ส่ง OTP ผ่าน SMS Gateway ในไทย หรือส่ง Audit Log ลง Apache Kafka)
Mental Model #01 ภาพเปรียบเทียบเชิงกายภาพในชีวิตประจำวัน

The Hotel Keycard Desk vs. The Tenant Apartments

เพื่อให้เห็นภาพการทำงาน ให้เปรียบเทียบ Keycloak เสมือน "เคาน์เตอร์แผนกต้อนรับของโรงแรมหรู": ผู้เข้าพัก (User) ไม่จำเป็นต้องมีกุญแจห้องถาวร แต่จะเดินมาที่แผนกต้อนรับเพื่อแสดงบัตรประจำตัว เมื่อผ่านการตรวจสอบ เคาน์เตอร์จะยื่น "คีย์การ์ดดิจิทัล (Token)" ให้ เมื่อผู้เข้าพักจะเข้าห้องพักหรือใช้บริการฟิตเนส (Resource API) ก็เพียงแค่แตะคีย์การ์ด โดยที่ประตูห้องพักไม่จำเป็นต้องจำประวัติหรือรหัสผ่านของผู้เข้าพักเลย!

DOCKER BRIDGE NETWORK: kc-network Keycloak Server (Quarkus Runtime Engine) HTTP: 8080 (Traffic) | Probes: 9000 (/health) Master Realm (Management Plane) • Super Administrator • Provisioning Realms • Global System Config • CLI: kcadm.sh Access ⚠️ BLAST RADIUS สูงสุด ห้ามใส่ Business Users หรือ Clients ทั่วไปในนี้เด็ดขาด Business Realm: "app-dev" (Tenant Security Boundary) • End Users & Passwords • OIDC Clients (SPA / API) • Realm & Client Roles • Dedicated RSA Keys ✅ ISOLATED TENANT หาก Realm นี้เกิดข้อผิดพลาด ระบบและ Realm อื่นจะไม่พังตาม Agroal Pool PostgreSQL 16 Engine Database: keycloak_db (Port: 5432) Core Database Schema Tables: • USER_ENTITY (id, username, email) • CREDENTIAL (hashes, salt) | USER_ATTRIBUTE • max_connections: 150 • Liquibase: DATABASECHANGELOGLOCK ✅ ACID Transactional Storage 📁 postgres_data Host Persistent Volume Mount
Case Study #01 Production Outage Post-Mortem

The 47-Minute "Ghost Realm" Disaster: Ephemeral Database & Agroal Pool Starvation

Direct Business Loss
$420,000

สูญเสียมูลค่า GMV ในช่วง 47 นาทีแรกของแคมเปญ 11.11 เนื่องจากลูกค้ากว่า 120,000 คนล็อกอินและชำระเงินไม่ได้

Root Cause Mechanism
start-dev with In-Memory H2 & Unbounded Pool

รันโหมด Dev ใน Production ส่งผลให้ข้อมูลหายเมื่อ Pod รีสตาร์ท และ Agroal Pool ไม่ถูกจำกัดจนสูญเสียการควบคุม

Architectural Takeaway
Decoupled State & AOT Optimization

แยก State ลง PostgreSQL, ใช้คำสั่ง start --optimized, และคำนวณ Pool Size สัมพันธ์กับ Database เสมอ

สถานการณ์จริง: ในคืนเปิดตัวแคมเปญ Flash Sale ประจำปี ทีมวิศวกรของบริษัทอีคอมเมิร์ซแห่งหนึ่งได้นำ Keycloak มาใช้เป็น Identity Provider (IdP) หลัก แต่ด้วยความคุ้นชินจากการทดสอบในเครื่อง Local ไฟล์ Kubernetes Deployment จึงถูกกำหนดคำสั่งเริ่มต้นเป็น start-dev โดยไม่ได้ต่อ Database ภายนอก และละเลยการ Mount Persistent Volume

เมื่อทราฟฟิกลูกค้าหลั่งไหลเข้ามามากกว่า 14,000 Requests Per Minute (RPM) ในนาทีแรก หน่วยความจำ JVM พุ่งแตะ 98% จนถูก Kubernetes OOMKilled รีสตาร์ท Pod อัตโนมัติ ผลลัพธ์ที่ตามมาคือ Realm Configuration ทั้งหมด, ข้อมูล Active Sessions และกุญแจ Public Key Pair (JWKS) สูญหายไปทั้งหมดทันที!

เมื่อ Pod บูตขึ้นมาใหม่ Keycloak เข้าสู่หน้าจอ Initial Setup เสมือนเพิ่งติดตั้งครั้งแรก ส่งผลให้ Access Token เดิมนับแสนใบถูก Microservices เบื้องหลังปฏิเสธ (Signature Mismatch) ทันที ส่งผลให้ระบบล่มสนิทเป็นเวลากว่า 47 นาทีกว่าจะกู้คืนข้อมูลสำรองได้

Defense Argument สำหรับคุยกับทีม: "Keycloak ในยุค Quarkus Runtime ไม่ใช่เซิร์ฟเวอร์แบบ Standalone ที่รันอย่างไรก็ได้ คำสั่ง start-dev มีไว้สำหรับการเขียนโค้ดบนเครื่อง Dev เท่านั้น เพราะจะผ่อนปรนความปลอดภัย (Insecure HTTP), ไม่แคช Indexing และใช้ฐานข้อมูลชั่วคราว การนำเข้า Production ต้องปฏิบัติตามหลักการ Decoupled Persistence: แยกข้อมูลลง PostgreSQL, คำนวณ Agroal Connection Pool ให้แม่นยำ และทำการ Pre-build ด้วยคำสั่ง kc.sh build ก่อนเสมอ!"
Hands-on Breakdown แกะโครงสร้างคำสั่ง & ลงมือสร้างจริง 3 เลเวล

Anatomy of Keycloak Configuration & Health Probes

ตั้งแต่ Keycloak ยุค Quarkus เป็นต้นมา ตัวแปร Configuration ทั้งหมดจะขึ้นต้นด้วยพรีฟิกซ์ KC_* เสมอ โดยการตั้งค่าที่ถูกต้องต้องควบคุมทั้ง Database Connection, Reverse Proxy Forwarding, และ Health Metrics:

Environment Variable ชนิดของพารามิเตอร์ หน้าที่ทางวิศวกรรม ข้อกำหนดระดับ Production
KC_DB=postgres Build-time สั่งให้ Quarkus โหลดเฉพาะ Driver ของ PostgreSQL และตัด Driver อื่นทิ้ง ห้ามปล่อยว่าง ไม่งั้นจะ fallback ไปใช้ H2 in-memory
KC_DB_URL Runtime JDBC String ระบุโฮสต์และพอร์ตฐานข้อมูล (เช่น jdbc:postgresql://postgres:5432/keycloak_db) ต้องชี้ไปยัง Service Name ภายใน Docker Network
KC_DB_POOL_MAX_SIZE Runtime จำกัดจำนวน Connection สูงสุดที่ Agroal Pool ของแต่ละ Pod จะเปิดค้างไว้ ผลคูณของทุก Pod ต้องไม่เกิน max_connections ของ DB
KC_HEALTH_ENABLED=true Build-time เปิดใช้งาน Endpoint /health/live และ /health/ready บนพอร์ต 9000 จำเป็นสำหรับ Kubernetes Liveness/Readiness Probes
KC_BOOTSTRAP_ADMIN_* Runtime กำหนดชื่อและรหัสผ่านเริ่มต้นของ Admin ใน Master Realm อย่างเป็นทางการ มาแทนที่ KEYCLOAK_ADMIN เดิมที่ประกาศ deprecated
KC_PROXY_HEADERS=xforwarded Runtime บอกให้ Keycloak เชื่อถือ Header X-Forwarded-Proto และ X-Forwarded-Host จาก Reverse Proxy ป้องกันปัญหา Redirect URI กลายเป็น http แทน https
LEVEL 1: Ephemeral Exploratory Run (Dev Only) CLI Command

คำสั่งบรรทัดเดียวสำหรับทดลองสำรวจ Admin Console ชั่วคราว (ข้อมูลทั้งหมดจะสูญหายทันทีที่ Container ถูกปิด)

# รันโหมด Dev ชั่วคราว (ใช้ In-memory H2 DB ข้อมูลจะสูญหายทันทีที่ Stop)
docker run --name keycloak-sandbox -p 8080:8080 \
  -e KEYCLOAK_ADMIN=superadmin \
  -e KEYCLOAK_ADMIN_PASSWORD=AdminSuperSecret2026! \
  quay.io/keycloak/keycloak:24.0.5 start-dev
LEVEL 2: Persistent Multi-Container Stack via Docker Compose ✅ Local Production-Ready

โครงสร้างแยก PostgreSQL Database พร้อม Persistent Volume Mount, Healthcheck, และการเปิด Health Endpoints

version: '3.8'

services:
  postgres:
    image: postgres:16-alpine
    container_name: keycloak-postgres
    environment:
      POSTGRES_DB: keycloak_db
      POSTGRES_USER: kc_db_user
      POSTGRES_PASSWORD: DB_Secret_SecurePassword_2026!
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - kc-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U kc_db_user -d keycloak_db"]
      interval: 5s
      timeout: 5s
      retries: 5

  keycloak:
    image: quay.io/keycloak/keycloak:24.0.5
    container_name: keycloak-core
    command: start-dev
    environment:
      KC_DB: postgres
      KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak_db
      KC_DB_USERNAME: kc_db_user
      KC_DB_PASSWORD: DB_Secret_SecurePassword_2026!
      KC_DB_POOL_MIN_SIZE: 10
      KC_DB_POOL_MAX_SIZE: 30
      KEYCLOAK_ADMIN: superadmin
      KEYCLOAK_ADMIN_PASSWORD: AdminSuperSecret2026!
      KC_HEALTH_ENABLED: "true"
      KC_METRICS_ENABLED: "true"
      KC_HTTP_ENABLED: "true"
    ports:
      - "8080:8080"
      - "9000:9000"
    depends_on:
      postgres:
        condition: service_healthy
    networks:
      - kc-network

volumes:
  postgres_data:
    driver: local

networks:
  kc-network:
    driver: bridge
LEVEL 3: Architectural Refactoring (Anti-Pattern vs Production-Ready) Zero-Downtime Pipeline
❌ Flawed & Dangerous Setup
  • ใช้คำสั่ง start-dev ในระบบ Production
  • สร้าง Business Users และ Clients ปนเปื้อนลงใน master realm
  • ไม่จำกัด KC_DB_POOL_MAX_SIZE ทำให้ connection พุ่งชนเพดาน PostgreSQL
  • เขียนรหัสผ่านใหม่แบบ Plaintext ทับลงในตาราง CREDENTIAL ตอนลืมรหัสผ่าน
  • ไม่เปิด KC_PROXY_HEADERS ทำให้ Redirect URI กลายเป็น http ไม่ปลอดภัย
# ผลลัพธ์: ล่มทันทีเมื่อทราฟฟิกสูง, ข้อมูลกระจัดกระจาย, และระบบ Hash ตรวจสอบรหัสผ่านพังทลาย
✅ Production-Grade Architecture
  • Pre-build ด้วย kc.sh build แล้วรันด้วย start --optimized
  • สร้าง Business Realm (เช่น app-dev) แยกขาดจาก Master Realm อย่างเด็ดขาด
  • คำนวณ Pool: (Replicas × KC_DB_POOL_MAX_SIZE) < max_connections
  • กู้คืนรหัสผ่านด้วย CLI kcadm.sh หรือตัวแปร Bootstrap Admin ทางการ
  • ตั้งค่า KC_PROXY_HEADERS=xforwarded คู่กับ Reverse Proxy ที่รองรับ TLS
# เสถียร: สตาร์ทเร็วระดับเสี้ยววินาที, รองรับโหลดสูง, และปลอดภัยตามมาตรฐาน ISO/IEC 27001
Simulator #01 แบบจำลองสถาปัตยกรรม & การคำนวณ Connection Pool

Keycloak Agroal Pool & Worker Contention Simulator

ทดลองปรับแต่งตัวแปรเพื่อดูว่าเมื่อมีคำขอ Login เข้ามาพร้อมกัน หากกำหนดขนาด Database Pool หรือสัดส่วน Node ไม่สัมพันธ์กับ PostgreSQL ขีดจำกัดของระบบจะพังทลายที่จุดใดแบบ Real-time

Concurrent Logins (Requests/sec) 250 req/s
ปริมาณผู้ใช้ที่พยายามแลก Token หรือ Login พร้อมกันใน 1 วินาที
Keycloak Replicas (Pod Nodes) 3 Pods
จำนวนโหนด Keycloak ในคลัสเตอร์
KC_DB_POOL_MAX_SIZE (Per Pod) 30
ขนาด Pool สูงสุดของแต่ละโหนด (Total = Pods × Pool Size)
PostgreSQL max_connections 120
ขีดจำกัด Connections สูงสุดของ PostgreSQL instance
P99 Auth Latency
32 ms
Ultra Fast & Healthy
Total Active Connections
90 / 120
3 Pods × 30 Connections
System Health Status
STABLE
No Starvation Detected
Telemetry Diagnostic Stream Total Load: 75%
System operating smoothly within capacity. All user authentication handshakes completing without database thread contention.
Production Rule: Total Max Pool = Pods × KC_DB_POOL_MAX_SIZE. ต้องมีขนาดน้อยกว่า max_connections ของ PostgreSQL โดยเหลือเผื่อไว้ 15–20 slots สำหรับ Superuser และ Backup เสมอ!
Active Recall Comprehensive Exam 12 Production Scenarios (100% Aligned with Content)

Day 1 Architecture & Engineering Mastery Exam

ครอบคลุมนิยาม Keycloak, 7 Core Subsystems, Quarkus Runtime, Agroal Pool, Liquibase Locks และ Master Isolation

Live Score
0/12 answered
0 / 12
🎯

Day 1 Practical Deliverable (ภารกิจประจำวัน)

ก่อนก้าวไปสู่ Day 2 (The Core OIDC Protocol & Authorization Code with PKCE) คุณต้องทำภารกิจต่อไปนี้ให้สำเร็จบนเครื่องของคุณ: