--- tags: - project/sriphat - security - sso - keycloak - rbac created: 2026-05-07 status: active --- # Security Strategy ## หลักการออกแบบ ระบบออกแบบตามหลัก **Defense in Depth** สำหรับสภาพแวดล้อมโรงพยาบาล: 1. **Network Isolation** — ทุก service อยู่ใน `shared_data_network` 2. **Centralized Authentication** — SSO ผ่าน Keycloak เท่านั้น 3. **Schema Separation** — แยก raw / analytics / production data 4. **Row-Level Security** — PostgreSQL RLS จำกัดข้อมูลต่อ user 5. **API Key Management** — Permission-based API access --- ## Network Security ``` Internet │ ▼ Nginx Reverse Proxy (port 80/443) │ │ ← ทุก request ต้องผ่าน Nginx │ shared_data_network (Docker internal) ├── keycloak ├── postgres ├── sdp-supabase-* (12 containers) ├── apiservice ├── superset ├── airflow-* ├── minio └── redis ``` **Rules:** - ไม่มี service ใดที่ bind ตรงกับ `0.0.0.0` ยกเว้นผ่าน Nginx - Redis ไม่ expose port ออกภายนอก - Supabase services ไม่ expose port ออกภายนอก (ผ่าน Kong เท่านั้น) --- ## Authentication (SSO with Keycloak) ### Flow ``` User │ ├─ Web UI → Keycloak (OIDC Login) → redirect back with token │ └─ API Client → API Key (จาก Admin UI) → Bearer token ``` ### Keycloak Realms | Realm | Services | |-------|---------| | `master` | Admin (ปิด public access) | | `sriphat` | Superset, MinIO, Airflow, API Service | ### Client Configurations | Service | Client ID | Flow | |---------|-----------|------| | API Service | `apiservice` | Authorization Code | | Superset | `superset-client` | Authorization Code | | MinIO | `minio-client` | Authorization Code + PKCE | | Airflow | `airflow-client` | Authorization Code | --- ## API Key Security (API Service) ### Permission System ``` API Client (ระบบที่ขอใช้ API) │ └── API Keys (ถูก encrypt ด้วย AES) │ └── Permissions: - feed.checkpoint:write - (เพิ่มได้ตามต้องการ) ``` ### API Key Lifecycle ```bash # 1. Admin สร้าง API Client POST /apiservice/admin/api-clients # 2. Generate API Key สำหรับ Client POST /apiservice/admin/api-keys/generate ?client_id=1 &permissions=feed.checkpoint:write &name=his-production-key # 3. ใช้งาน API Key curl -H "Authorization: Bearer " \ https://ai.sriphat.com/apiservice/api/v1/feed/checkpoint ``` --- ## Database Security (Schema Separation) ### PostgreSQL Schemas | Schema | ใช้งาน | สิทธิ์ | |--------|--------|--------| | `public` | Default | แล้วแต่ config | | `raw_data` | ข้อมูลดิบจาก Airbyte | Airflow write, BI read-only | | `analytics` | ข้อมูลที่ transform แล้ว | BI read-only | | `operationbi` | Operation KPIs | API Service write, Superset read | | `fastapi` | API Service metadata | API Service only | | `_analytics` | Supabase Logflare | Internal only | | `_realtime` | Supabase Realtime | Internal only | ### Row-Level Security (RLS) ```sql -- ตัวอย่าง: จำกัดข้อมูลตาม department ALTER TABLE patient_data ENABLE ROW LEVEL SECURITY; CREATE POLICY department_isolation ON patient_data USING (department = current_setting('app.current_department')); -- Set context ใน connection SET app.current_department = 'OPD'; ``` --- ## Secrets Management ### ไฟล์ Secrets | ไฟล์ | ความสำคัญ | ต้องทำ | |------|---------|--------| | `.env.global` | HIGH | ไม่ commit ลง git | | `02-supabase/.env` | HIGH | ไม่ commit ลง git | | `03-apiservice/.env` | HIGH | ไม่ commit ลง git | | `07-minio/.env` | HIGH | ไม่ commit ลง git | ### Key Secrets ที่ต้อง Rotate | Secret | Location | แนะนำ Rotation | |--------|----------|--------------| | `DB_PASSWORD` | `.env.global` | 90 วัน | | `JWT_SECRET` (Supabase) | `02-supabase/.env` | เมื่อมีเหตุ | | `KEYCLOAK_ADMIN_PASSWORD` | `.env.global` | 90 วัน | | `ADMIN_SECRET_KEY` (API) | `03-apiservice/.env` | 90 วัน | | `MINIO_ROOT_PASSWORD` | `07-minio/.env` | 90 วัน | | `AIRFLOW__CORE__FERNET_KEY` | `05-airflow/.env` | ไม่ rotate (data loss) | | `SUPERSET_SECRET_KEY` | `.env.global` | ไม่ rotate (session loss) | --- ## Security Checklist ### Pre-Production - [ ] เปลี่ยน passwords ทั้งหมดจาก default - [ ] เปิด HTTPS ใน Nginx (Let's Encrypt หรือ internal CA) - [ ] ตั้งค่า Keycloak realm `sriphat` (ไม่ใช่ `master`) - [ ] เชื่อมต่อ LDAP/AD ของโรงพยาบาล - [ ] Enable RLS ใน PostgreSQL - [ ] ตั้งค่า firewall rules (จำกัด inbound ports) - [ ] Setup audit logging - [ ] กำหนด session timeout ใน Keycloak ### Ongoing - [ ] Review API Keys ที่ active ทุก 30 วัน - [ ] Monitor Dozzle สำหรับ unusual access patterns - [ ] Backup secrets ไว้ใน secure vault (HashiCorp Vault หรือ similar) - [ ] Rotate passwords ตามกำหนด --- ## SSL/TLS Configuration Nginx จัดการ SSL termination: ```nginx server { listen 443 ssl; server_name ai.sriphat.com; ssl_certificate /etc/nginx/ssl/cert.pem; ssl_certificate_key /etc/nginx/ssl/key.pem; # Force HTTPS # Redirect http → https ผ่าน Nginx } ``` --- ## Related - [[00-Project-Overview]] - [[01-Infrastructure]] (Keycloak setup) - [[03-API-Service]] (API Key management) - [[08-Operations-Runbook]]