File size: 22,002 Bytes
cb6a2d8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 | # MedOS Admin Guide
Complete guide for deploying, configuring, and managing the MedOS platform.
---
## Table of Contents
1. [Architecture Overview](#architecture-overview)
2. [Deployment Guide](#deployment-guide)
3. [Admin Panel](#admin-panel)
4. [LLM Provider Setup](#llm-provider-setup)
5. [Email (SMTP) Configuration](#email-smtp-configuration)
6. [Medicine Scanner Setup](#medicine-scanner-setup)
7. [Nearby Finder Setup](#nearby-finder-setup)
8. [Environment Variables Reference](#environment-variables-reference)
9. [Troubleshooting](#troubleshooting)
---
## Architecture Overview
MedOS runs as **3 independent HuggingFace Spaces** + an optional **Vercel frontend**:
```
┌─────────────────────────────────────────────────────────────┐
│ User's Browser │
│ │
│ Vercel (optional) OR HuggingFace Space │
│ ai-medical-chabot.com huggingface.co/spaces/ │
│ Frontend only ruslanmv/MediBot │
│ /api/proxy/* → MediBot Full app (FE + BE) │
└──────────┬──────────────────────────────┬───────────────────┘
│ │
▼ ▼
┌─────────────────────────────────────────────────────────────┐
│ MediBot Space (ruslanmv/MediBot) │
│ Next.js 14 + SQLite │
│ │
│ /api/chat → LLM providers (Llama, Qwen, Gemma, etc.) │
│ /api/auth/* → User auth (register, login, verify) │
│ /api/nearby → Proxy to MetaEngine-Nearby │
│ /api/scan → Proxy to Medicine-Scanner │
│ /api/admin/* → Admin panel APIs │
│ /api/health → Health check │
└──────────┬──────────────────────┬───────────────────────────┘
│ │
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ Medicine-Scanner │ │ MetaEngine-Nearby │
│ (Gradio SDK) │ │ (Gradio SDK) │
│ │ │ │
│ Qwen2.5-VL-72B │ │ OpenStreetMap │
│ Image → JSON │ │ Overpass API │
│ │ │ Nominatim geocoder │
└───────────────────────┘ └──────────────────────┘
```
---
## Deployment Guide
### Prerequisites
- HuggingFace account with write token
- (Optional) Vercel account for custom domain
- (Optional) SMTP credentials for email verification
### Required Tokens
| Token | Purpose | How to Create |
|-------|---------|---------------|
| **HF_TOKEN** (write) | Deploy Spaces, manage secrets | [huggingface.co/settings/tokens](https://huggingface.co/settings/tokens) → Fine-grained → Repo write |
| **HF_TOKEN_INFERENCE** | Medicine Scanner AI inference | [Create here](https://huggingface.co/settings/tokens/new?ownUserPermissions=inference.serverless.write&tokenType=fineGrained) → Check "Make calls to Inference Providers" |
---
### Deploy MediBot (Main App)
This is the core application — chat, health tracker, auth, admin panel.
```bash
# 1. Set your HuggingFace token
export HF_TOKEN=hf_your_write_token_here
# 2. Deploy (assembles web/ + backend, rewrites API paths, pushes)
bash 9-HuggingFace-Global/scripts/deploy-hf.sh
# 3. Verify
curl https://ruslanmv-medibot.hf.space/api/health
# → {"status":"ok"}
```
**What it does:**
- Copies `9-HuggingFace-Global/` (backend) as the base
- Overlays `web/` (frontend components, hooks, styles)
- Rewrites `/api/proxy/` → `/api/` in all frontend files
- Force-pushes to `ruslanmv/MediBot` HF Space
**After deployment**, set these secrets in the Space settings:
| Secret | Value | Required? |
|--------|-------|-----------|
| `HF_TOKEN` | Your HF token (for LLM inference) | Yes |
| `HF_TOKEN_INFERENCE` | Token with inference permissions | For scanner proxy |
| `NEARBY_URL` | `https://ruslanmv-metaengine-nearby.hf.space` | Default works |
| `SCANNER_URL` | `https://ruslanmv-medicine-scanner.hf.space` | Default works |
| `DB_PATH` | `/data/medos.db` | Default works |
---
### Deploy Medicine Scanner
AI-powered medicine label reader using Qwen2.5-VL-72B.
```bash
export HF_TOKEN=hf_your_write_token_here
bash 11-Medicine-Scanner/deploy-scanner.sh
# Verify
curl https://ruslanmv-medicine-scanner.hf.space/api/health
# → {"status":"ok","service":"medicine-scanner"}
```
**After deployment**, set this secret in Space settings:
| Secret | Value | Required? |
|--------|-------|-----------|
| `HF_TOKEN` | Token with "Make calls to Inference Providers" permission | Yes |
**Test the scanner:**
```bash
curl -X POST https://ruslanmv-medicine-scanner.hf.space/api/scan \
-F "image=@photo_of_medicine.jpg"
```
---
### Deploy MetaEngine Nearby Finder
Finds pharmacies and doctors using OpenStreetMap.
```bash
export HF_TOKEN=hf_your_write_token_here
bash 12-MetaEngine-Nearby/deploy-nearby.sh
# Verify
curl https://ruslanmv-metaengine-nearby.hf.space/api/health
# → {"status":"ok","service":"nearby-finder"}
```
No secrets needed — uses free OpenStreetMap APIs.
**Test the finder:**
```bash
curl -X POST https://ruslanmv-metaengine-nearby.hf.space/api/search \
-H "Content-Type: application/json" \
-d '{"lat": 40.7128, "lon": -74.006, "entity_type": "pharmacy", "limit": 5}'
```
---
### Deploy Vercel Frontend (Optional)
For custom domains (e.g., `ai-medical-chabot.com`):
1. Go to [vercel.com](https://vercel.com) → Import Git Repository
2. **Root Directory:** `web`
3. **Framework:** Next.js
4. **Environment Variables:**
| Variable | Value |
|----------|-------|
| `NEXT_PUBLIC_BACKEND_URL` | `https://ruslanmv-medibot.hf.space` |
5. Click **Deploy**
6. Add custom domain in Vercel → Settings → Domains
The Vercel frontend is a thin proxy — all API calls go to the MediBot Space.
---
## Admin Panel
### How to Access
1. Go to your MedOS instance (HF Space or Vercel URL)
2. Log in with the default admin account:
- **Email:** `admin@medos.health`
- **Password:** `admin123456`
3. **Change the password immediately** after first login
4. The **Admin** section appears in the desktop sidebar (bottom, under Tools)
### Admin Panel Tabs
#### Overview
Platform statistics at a glance:
- Total users, verified users, admin count
- Health records count, chat sessions count
- Active sessions (logged-in users)
- Health data breakdown by type (medications, vitals, etc.)
- Registration trend chart (last 30 days)
#### Users
User management:
- Search by email or display name
- Paginated list (20 users per page)
- Per-user info: email, verification status, health records count, chat count
- **Reset Password**: Set a temporary password for a user (invalidates all sessions)
- **Delete User**: Admin-only, requires email confirmation, CASCADE deletes all data
#### LLM
Test all AI model providers:
- Click **"Test All Providers"** to test 12 models in parallel
- Shows status (green/red), latency (ms), response preview
- Summary: total/online/offline counts
- Explains the routing fallback chain
**Current model cascade (tested and verified):**
| Model | Size | Provider |
|-------|------|----------|
| Llama 3.3 70B :sambanova | 70B | SambaNova |
| Llama 3.3 70B :together | 70B | Together |
| Llama 3.3 70B (auto) | 70B | Auto-routed |
| Qwen 2.5 72B | 72B | Auto-routed |
| Qwen3 235B (MoE) | 235B | Auto-routed |
| Gemma 3 27B | 27B | Auto-routed |
| Llama 3.1 70B | 70B | Auto-routed |
| Qwen3 32B | 32B | Auto-routed |
| DeepSeek V3 | 671B | Auto-routed |
If all models fail, the system falls back to **15 pre-cached medical FAQ responses** (always works, even offline).
#### Email
SMTP configuration for email verification and password reset:
| Field | Description | Example |
|-------|-------------|---------|
| SMTP Host | Mail server hostname | `smtp.gmail.com` |
| SMTP Port | Usually 587 (TLS) or 465 (SSL) | `587` |
| SMTP Username | Your email account | `medos@yourdomain.com` |
| SMTP Password | App password (not your login password) | `xxxx xxxx xxxx xxxx` |
| From Email | Sender display name + email | `MedOS <noreply@medos.health>` |
| Recovery Email | Support contact for users | `support@medos.health` |
**Gmail setup:**
1. Go to [myaccount.google.com/apppasswords](https://myaccount.google.com/apppasswords)
2. Generate an app password
3. Use your Gmail as SMTP username, app password as SMTP password
4. Host: `smtp.gmail.com`, Port: `587`
**If SMTP is not configured:** Verification codes are logged to the console (visible in Space logs). This is fine for development but not production.
#### Server
Server-side configuration:
| Setting | Description | Default |
|---------|-------------|---------|
| Default Preset | Default AI model for new users | `free-best` |
| Ollama Base URL | Local Ollama server (if running) | `http://localhost:11434` |
| HF Default Model | Default model for HF Inference | `meta-llama/Llama-3.3-70B-Instruct` |
| Application URL | Public URL (used in emails) | `https://ruslanmv-medibot.hf.space` |
| Allowed Origins | CORS origins (comma-separated) | Your Vercel URL |
Changes are saved to `/data/medos-config.json` and persist across restarts.
---
## LLM Provider Setup
### How the AI Chat Works
When a user sends a message:
```
1. Emergency triage (19 patterns, instant) — bypasses LLM entirely
2. RAG context (medical knowledge base, 23 topics)
3. System prompt (WHO/CDC/NHS guidelines, user's language + country)
4. LLM provider chain:
a. OllaBridge (if configured) — custom gateway
b. HuggingFace Inference — 9-model cascade
c. Cached FAQ (always works) — 15 pre-built answers
```
### HuggingFace Token Requirements
The `HF_TOKEN` secret on the MediBot Space needs **"Make calls to Inference Providers"** permission:
1. Go to [huggingface.co/settings/tokens](https://huggingface.co/settings/tokens/new?ownUserPermissions=inference.serverless.write&tokenType=fineGrained)
2. Create a **Fine-grained** token
3. Check **"Make calls to Inference Providers"**
4. Copy the token
5. Set it as `HF_TOKEN` in MediBot Space settings
### Testing LLM Health
**From the Admin Panel:**
Admin → LLM tab → "Test All Providers"
**From the command line:**
```bash
HF_TOKEN=hf_xxx python scripts/check-llm-health.py
```
**Output:**
```
OK Llama-3.3-70B-Instruct 640ms OK
OK Qwen2.5-72B-Instruct 1366ms OK
OK Qwen3-235B-A22B 1785ms OK
OK gemma-3-27b-it 951ms OK
FAIL Llama-3.3-70B-Instruct:sambanova 2549ms 402 Payment Required
Summary: 12/13 models online (1 degraded)
```
### Adding a Custom OllaBridge Gateway
If you run your own LLM server:
```bash
# Set in HF Space settings
OLLABRIDGE_URL=https://your-server.com
OLLABRIDGE_API_KEY=sk-your-key
```
OllaBridge is tried FIRST in the fallback chain, before HuggingFace.
---
## Email (SMTP) Configuration
### Quick Setup (Gmail)
1. Enable 2FA on your Google account
2. Generate an app password: [myaccount.google.com/apppasswords](https://myaccount.google.com/apppasswords)
3. In MedOS Admin → Email tab:
- Host: `smtp.gmail.com`
- Port: `587`
- User: `your.email@gmail.com`
- Password: (the app password from step 2)
- From: `MedOS <your.email@gmail.com>`
4. Click **Save Configuration**
### Other Providers
| Provider | Host | Port |
|----------|------|------|
| Gmail | `smtp.gmail.com` | 587 |
| Outlook | `smtp.office365.com` | 587 |
| SendGrid | `smtp.sendgrid.net` | 587 |
| AWS SES | `email-smtp.us-east-1.amazonaws.com` | 587 |
| Mailgun | `smtp.mailgun.org` | 587 |
### What Emails Are Sent
| Email | When | Expiry |
|-------|------|--------|
| Verification code | User registers | 15 minutes |
| Password reset code | User clicks "Forgot password" | 1 hour |
| Welcome email | After email verification | N/A |
### Dev Mode (No SMTP)
If SMTP is not configured, all verification codes are **logged to the console**. Check Space logs:
```
[EMAIL] To: user@example.com
[EMAIL] Subject: MedOS — verify your email
[EMAIL] Body: Your verification code is: 847291
```
---
## Medicine Scanner Setup
### How the Scanner Works on Each Platform
| Platform | Behavior |
|----------|----------|
| **Desktop (Chrome/Firefox/Edge)** | Live webcam preview inside modal with viewfinder overlay. User positions medicine, clicks "Capture". Falls back to file upload if webcam not available. |
| **Android** | Opens native camera app directly. Photo is sent to AI immediately. |
| **iPhone/iPad** | Opens native camera app directly. Same as Android. |
### Webcam Permissions
For the desktop webcam to work:
- The site must be served over **HTTPS** (required by browsers for `getUserMedia`)
- User must **allow camera access** when prompted
- `Permissions-Policy: camera=(self)` header is already set
### Token Requirements
The Medicine Scanner Space needs a HuggingFace token with **"Make calls to Inference Providers"** permission (same as LLM chat).
Set it as `HF_TOKEN` in the Medicine-Scanner Space settings.
### Models Used
| Model | Purpose | Fallback |
|-------|---------|----------|
| Qwen/Qwen2.5-VL-72B-Instruct | Primary (best quality) | → |
| google/gemma-3-27b-it | Fallback | N/A |
### How It Works
```
User takes photo → MedOS frontend
→ POST /api/scan (MediBot proxy)
→ POST /api/scan (Scanner Space)
→ Encode image as base64
→ Send to Qwen2.5-VL-72B with extraction prompt
→ Parse JSON response
→ Return: name, dose, form, category, expiry, instructions
```
---
## Nearby Finder Setup
### No Configuration Needed
MetaEngine-Nearby uses free APIs — no tokens or secrets required:
- **OpenStreetMap Overpass API** — pharmacy/doctor location data
- **Nominatim** — geocoding (city name → coordinates) and reverse geocoding
### How It Works
```
User enters location → MedOS frontend
→ POST /api/nearby (MediBot proxy)
→ POST /gradio_api/call/search_ui (MetaEngine Space)
→ Query Overpass API for pharmacies/doctors within radius
→ Calculate distance, ETA (walk/drive)
→ Generate Google Maps directions URLs
→ Return sorted results
```
### Overpass API Limits
- Free, no API key
- Rate limit: ~10,000 requests/day (shared)
- Timeout: 25 seconds per query
- If Overpass is slow, results may be empty — retry helps
---
## Environment Variables Reference
### MediBot Space
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `HF_TOKEN` | Yes | — | HuggingFace token (inference + write) |
| `DB_PATH` | No | `/data/medos.db` | SQLite database path |
| `ADMIN_EMAIL` | No | `admin@medos.health` | Default admin email |
| `ADMIN_PASSWORD` | No | `admin123456` | Default admin password |
| `SMTP_HOST` | No | — | SMTP server hostname |
| `SMTP_PORT` | No | `587` | SMTP port |
| `SMTP_USER` | No | — | SMTP username |
| `SMTP_PASS` | No | — | SMTP password |
| `FROM_EMAIL` | No | `MedOS <noreply@medos.health>` | Sender email |
| `APP_URL` | No | `https://ruslanmv-medibot.hf.space` | Public URL |
| `ALLOWED_ORIGINS` | No | `*` | CORS allowed origins |
| `NEARBY_URL` | No | `https://ruslanmv-metaengine-nearby.hf.space` | Nearby finder URL |
| `SCANNER_URL` | No | `https://ruslanmv-medicine-scanner.hf.space` | Scanner URL |
| `HF_TOKEN_INFERENCE` | No | — | Inference token for scanner proxy |
| `OLLABRIDGE_URL` | No | — | Custom OllaBridge gateway URL |
| `OLLABRIDGE_API_KEY` | No | — | OllaBridge API key |
| `DEFAULT_PRESET` | No | `free-best` | Default AI model preset |
### Medicine Scanner Space
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `HF_TOKEN` | Yes | — | Token with inference permissions |
### MetaEngine Nearby Space
No environment variables needed. Uses free OpenStreetMap APIs.
### Vercel Frontend
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `NEXT_PUBLIC_BACKEND_URL` | Yes | `https://ruslanmv-medibot.hf.space` | MediBot Space URL |
---
## Troubleshooting
### "All models failed" in chat
1. Go to Admin → LLM tab → Test All Providers
2. If all models show red: your `HF_TOKEN` doesn't have inference permissions
3. Fix: Create a new token at [huggingface.co/settings/tokens](https://huggingface.co/settings/tokens/new?ownUserPermissions=inference.serverless.write&tokenType=fineGrained)
4. Update the `HF_TOKEN` secret in MediBot Space settings
### Medicine Scanner shows "Scan failed"
1. Check the Scanner Space is running: visit [huggingface.co/spaces/ruslanmv/Medicine-Scanner](https://huggingface.co/spaces/ruslanmv/Medicine-Scanner)
2. If sleeping, any request will wake it (takes ~30 seconds)
3. Check `HF_TOKEN` secret is set with inference permissions
### Nearby search returns no results
1. Check MetaEngine Space is running: visit [huggingface.co/spaces/ruslanmv/MetaEngine-Nearby](https://huggingface.co/spaces/ruslanmv/MetaEngine-Nearby)
2. Overpass API may be slow — retry after a few seconds
3. Try a different location (some areas have fewer OSM entries)
### Chat returns 504 on Vercel (ai-medical-chabot.com)
This happens when the MediBot Space is sleeping and the Vercel proxy times out waiting for it to wake.
**Fixes:**
1. `vercel.json` sets `maxDuration: 60` (increased from 30s)
2. If still timing out, wake MediBot first: visit [huggingface.co/spaces/ruslanmv/MediBot](https://huggingface.co/spaces/ruslanmv/MediBot) and wait ~30s
3. For always-on, upgrade the MediBot HF Space to a paid plan
**Why it happens:**
- Vercel proxy → MediBot (sleeping, 30s cold start) → LLM (5-10s) = 40s total
- Vercel free tier allows max 60s per function call
### Desktop webcam not working in scanner
1. Ensure the site is served over **HTTPS** (browsers block `getUserMedia` on HTTP)
2. User must click "Allow" on the camera permission prompt
3. If webcam is blocked, the scanner shows "Upload photo" as fallback
4. Check browser settings: Settings → Privacy → Camera → allow your domain
### Email verification codes not received
1. Check Admin → Email tab — is SMTP configured?
2. If not configured, codes appear in Space logs (Container tab)
3. For Gmail: use an app password, not your login password
4. Check spam folder
### Space shows "Building" or "Error"
1. Check Space logs at `huggingface.co/spaces/ruslanmv/SpaceName` → Logs tab
2. Common issues:
- Missing `HF_TOKEN` secret → auth errors
- Dependency conflict → check requirements.txt
- Port mismatch → ensure app runs on port 7860
### Admin panel not visible
1. You must be logged in as an admin user
2. Default admin: `admin@medos.health` / `admin123456`
3. The Admin section only appears in the **desktop sidebar** (not mobile drawer for security)
4. If the admin account doesn't exist, restart the Space (it auto-seeds on startup)
### HF Space goes to sleep
Free-tier HF Spaces sleep after ~15 minutes of inactivity.
- Any request wakes them automatically (~30-60 seconds)
- The MedOS frontend shows "waking up" status during this time
- For always-on, upgrade to a paid HF Space plan
### Database reset
If you need to reset the database:
1. Delete the persistent storage in Space settings
2. Restart the Space
3. The database will be recreated with a fresh admin account
---
## GitHub Actions (CI/CD)
Automated deployment is configured via GitHub workflows:
| Workflow | Trigger | Space |
|----------|---------|-------|
| `deploy-medibot.yml` | Push to `main` (changes in `9-HuggingFace-Global/` or `web/`) | MediBot |
| `deploy-medicine-scanner.yml` | Push to `main` (changes in `11-Medicine-Scanner/`) | Medicine-Scanner |
| `deploy-metaengine-nearby.yml` | Push to `main` (changes in `12-MetaEngine-Nearby/`) | MetaEngine-Nearby |
| `ci-medos-global.yml` | Push to any branch | Runs 88 tests + build |
### GitHub Secrets Required
Set these in **GitHub → Settings → Secrets → Actions**:
| Secret | Value |
|--------|-------|
| `HF_TOKEN` | HuggingFace write token |
| `HF_USERNAME` | `ruslanmv` (your HF username) |
| `HF_TOKEN_INFERENCE` | Token with inference permissions (for scanner) |
### Manual Deployment
All Spaces can also be deployed manually:
```bash
# MediBot
HF_TOKEN=hf_xxx bash 9-HuggingFace-Global/scripts/deploy-hf.sh
# Medicine Scanner
HF_TOKEN=hf_xxx bash 11-Medicine-Scanner/deploy-scanner.sh
# MetaEngine Nearby
HF_TOKEN=hf_xxx bash 12-MetaEngine-Nearby/deploy-nearby.sh
```
---
## Security Notes
- Default admin password MUST be changed after first login
- `HF_TOKEN` should have minimal required permissions
- Rate limiting is active on login (10/min) and register (5/min)
- Account deletion is admin-only (prevents data destruction attacks)
- Health data is stored in SQLite with CASCADE deletes
- CSP headers restrict script/connect sources
- All auth cookies are httpOnly with SameSite=Lax
---
*Last updated: April 2026*
*MedOS v1.0 — Free & Open Source*
|