- 01-infra/nginx-configs: add MinIO /minio/ and /minio-console/ location blocks (port 9000 S3 API, port 9001 Console UI, path stripping via rewrite) - 03-apiservice: integrate MinIO minio-python SDK for file upload - requirements.txt: add minio==7.2.11 - app/core/config.py: add MINIO_ENDPOINT, ACCESS_KEY, SECRET_KEY, BUCKET_FINANCE, USE_SSL - app/services/minio_client.py: new — upload_file(), get_presigned_url(), delete_file() - app/routes/pages.py: replace local /data/uploads/ write with MinIO upload to finance bucket - docker-compose.yml: pass MinIO env vars to container - .env.example: document MinIO vars - 07-minio/.env.example: add MINIO_SVC_ACCESS_KEY/SECRET_KEY section - 07-minio/README.md: add Python minio SDK and Airflow DAG usage guide - CLAUDE.md: project context (servers, SSH, paths, service distribution) - document-obsidiant/: initial Obsidian docs for all services
6.1 KiB
6.1 KiB
tags, created, status
| tags | created | status | |||||
|---|---|---|---|---|---|---|---|
|
2026-05-07 | active |
Security Strategy
หลักการออกแบบ
ระบบออกแบบตามหลัก Defense in Depth สำหรับสภาพแวดล้อมโรงพยาบาล:
- Network Isolation — ทุก service อยู่ใน
shared_data_network - Centralized Authentication — SSO ผ่าน Keycloak เท่านั้น
- Schema Separation — แยก raw / analytics / production data
- Row-Level Security — PostgreSQL RLS จำกัดข้อมูลต่อ user
- 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
# 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 <key>" \
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)
-- ตัวอย่าง: จำกัดข้อมูลตาม 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:
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